---
title: "Prompt-Residue Comments"
type: "ai-smell"
slug: "prompt-residue-comments"
url: "http://localhost:3000/en/ai-smells/prompt-residue-comments.md"
category: "Clarity"
description: "Comments that are artifacts of the generation conversation — restated prompts, step-by-step narration, chat asides, and placeholder elisions like `// ... rest of the code here` — committed into source instead of real documentation."
---
# Prompt-Residue Comments

> Comments that are artifacts of the generation conversation — restated prompts, step-by-step narration, chat asides, and placeholder elisions like `// ... rest of the code here` — committed into source instead of real documentation.

## Signs and Symptoms

A reviewer spots Prompt-Residue Comments when the comments document the _conversation that produced the code_ rather than the code itself. Four tells, often co-occurring:

* **Restated prompt** — a comment that paraphrases the request verbatim (`// Function to add two numbers`) above a function literally named `add`.
* **Step narration** — line-by-line play-by-play of obvious operations (`// Step 1: loop over the array`, `// increment i by 1` above `i++`).
* **Chat asides** — second-person, present-tense remarks aimed at _you_, the prompter (`// As requested, here is the updated handler`, `// Sure! Here's the fix`, `// Note: replace with your actual API key`).
* **Elision / placeholder residue** — `// ... rest of the code here`, `// keep your existing logic`, `// your code here`, `// TODO: implement error handling` left in committed source.

```ts
// Function to add two numbers and return the result   <- restates the prompt
function add(a: number, b: number): number {
  // Step 1: add the two numbers                        <- narrates the obvious
  const sum = a + b;
  return sum; // return the sum
}

// As requested, here is the updated handler            <- chat aside to "you"
export async function handler(req: Req, res: Res) {
  // ... keep your existing validation logic here ...   <- elision: real code dropped
  // TODO: implement error handling                     <- placeholder shipped as-is
  const user = await db.users.find(req.params.id);
  res.json(user);
}

```

The elision line is the dangerous one: it reads as documentation but is actually an instruction to a human to paste code that the model omitted — apply the block verbatim and the existing validation silently disappears. OX Security found "Comments Everywhere" in **90–100%** of AI-generated code in its 300+ repo study, describing them as markers that "look helpful but mainly support the AI itself, cluttering repositories."

## Reasons for the Problem

**Why models emit it**

* **Next-token mimicry of tutorial corpora.** The training mix is saturated with blog posts, StackOverflow answers, and docs where every line is explained for a learner. The model reproduces that didactic register — narration and restated intent — because it is the statistically likely continuation, not because the surrounding repo needs it.
* **Chat register bleed / sycophancy.** RLHF tunes assistants to be explanatory and agreeable in the _chat channel_. That conversational, second-person tone leaks into the _code channel_, producing "As requested…" and "Note: you should…" asides that make no sense once the code is detached from the conversation.
* **Reasoning narrated as comments.** Models externalize their plan ("Step 1… Step 2…") as inline comments — chain-of-thought leakage frozen into the file.
* **Elision is a chat affordance, misapplied.** In a chat reply, `// ... rest unchanged ...` is a polite way to avoid re-printing a file. When that reply is pasted or auto-applied to a real file, the affordance becomes literal residue — and literal data loss.
* **No repo context, so it restates the prompt.** Lacking the ticket, the domain, and the real "why," the model has nothing true to say in a comment, so it falls back to paraphrasing the only thing it has: your prompt. OX characterizes the comments as "internal markers to navigate context limits… dependence on short-term memory rather than true understanding."

**Why it hurts**

* **Review load.** Every narration line is noise a human must read past. OX's framing: AI "codes like a junior dev" at machine speed, and human review "cannot scale to match AI's output" — residue comments make each diff more expensive to review precisely when there are more diffs.
* **Correctness / data loss.** Elision placeholders (`// ...existing code...`) cause real code to be dropped when blocks are applied blindly.
* **Comment rot.** Restated-prompt comments duplicate the code's intent in prose; the prose drifts as the code changes, leaving actively misleading documentation — Fowler's classic _Comments_\-as-deodorant smell.
* **Hidden incompleteness.** `// TODO: implement error handling` is the model signaling it worked at the edge of its competence; shipped as-is, it is unfinished logic disguised as a tracked task.
* **Security tells.** `// replace with your actual API key` typically sits beside a hardcoded placeholder credential — the residue marks exactly the line a scanner (and an attacker) cares about.

## Treatment

**Prompting / generation tactics**

* Constrain the register: _"Output the complete file. Never abbreviate with `// ...`, `// rest of the code`, or `// existing code`. Do not narrate steps — comment only non-obvious rationale (the why). No conversational asides; this goes straight into a repo."_
* Ask for a **unified diff** rather than a prose-wrapped snippet, so omissions are explicit and applyable instead of hand-waved with an elision comment.
* Require the model to run the formatter and your lint config (e.g. `no-warning-comments` with custom terms) and report the result — closing the _"validate with the linter"_ loop catches placeholder/TODO residue automatically.
* Add a pre-commit / CI grep gate for residue markers (`rest of the code`, `your code here`, `existing code`, `As requested`, `Step \d`) and treat elision markers as a **hard blocker**, since they often mean code was silently dropped.

**The refactor**

Delete chat asides and narration outright. Where a comment merely restates _what_ the code does, that is the signal to make the code self-documenting — apply **Extract Function** and **Rename** so the name carries the intent, then keep only comments that explain a non-obvious _why_ (Fowler: _Remove comments that are deodorant for bad names_).

```ts
// before — prompt residue
// Create a function that validates an email address using a regex
function validateEmail(input) {
  // check if the input matches the email pattern
  const re = /^[^@]+@[^@]+\.[^@]+$/;
  // return true or false
  return re.test(input);
}

```

```ts
// after — name carries intent; the only comment explains the non-obvious why
const EMAIL_RE = /^[^@]+@[^@]+\.[^@]+$/; // intentionally loose: we only catch typos pre-send, not RFC 5322
const isValidEmail = (input: string): boolean => EMAIL_RE.test(input);

```

For elision residue, never apply the block as written — diff it against the current file and restore what the model dropped. For `// TODO: implement …`, either finish the logic or convert it into a tracked issue and fail the build on the placeholder term so it cannot ship as-is.

## Detected by

- **ESLint** `no-warning-comments` — Flags TODO/FIXME/XXX and custom configurable terms — set `terms` to catch placeholder residue like "your code here" or "rest of the code" (https://eslint.org/docs/latest/rules/no-warning-comments)
- **SonarQube / SonarSource** `S125` — Sections of code should not be commented out — flags elided/leftover commented-out blocks (https://rules.sonarsource.com/javascript/RSPEC-125/)
- **SonarQube / SonarSource** `S1135` — Track uses of "TODO" tags — surfaces placeholder TODO residue shipped as code (https://rules.sonarsource.com/javascript/RSPEC-1135/)
- **SonarQube / SonarSource** `S1134` — Track uses of "FIXME" tags (https://rules.sonarsource.com/javascript/RSPEC-1134/)
