Wrong feature

A stub shipped as "done"

桩代码冒充“已完成”

The agent reports the feature complete, but a function body is `pass`, `return null`, or `throw new Error("not implemented")`.

Applies to: Claude Code · Cursor · Codex · Copilot agent

Symptom

The summary says done. The UI or endpoint exists. The core function behind it is a placeholder, a TODO, or returns a hard-coded value.

Why it happens

Agents scaffold first and fill in later. When the session runs long or hits a hard part, the scaffold survives and the final message describes the plan rather than the code. agent-review lists this as AR035 "Incomplete implementation"; the Agentic SDLC handbook describes the related "Almost Done" trap.

Example

From the agent-review taxonomy (AR035).

python
def refund(order):
    """Issue a full refund to the customer."""
    pass  # placeholder; not what the diff claims

Copy-paste fixes

Pick the files for the agents you use. Snippets are in English so they work in any repo.

Rules

Claude Code: add to CLAUDE.md

CLAUDE.md
## No placeholders in "done" work
- Never report a task complete while any changed code contains `pass`, `TODO`, `FIXME`,
  `not implemented`, or a hard-coded return standing in for real logic.
- If you cannot finish a part, say so in the first line of your reply and list exactly what is stubbed.
- Before saying done, search the diff: `git diff | grep -nE "TODO|FIXME|not implemented|pass$"`.
Rules

Codex, Copilot coding agent and others: add to AGENTS.md

AGENTS.md
## No placeholders in "done" work
- Never report a task complete while any changed code contains `pass`, `TODO`, `FIXME`,
  `not implemented`, or a hard-coded return standing in for real logic.
- If you cannot finish a part, say so in the first line of your reply and list exactly what is stubbed.
- Before saying done, search the diff: `git diff | grep -nE "TODO|FIXME|not implemented|pass$"`.
Cursor rule

Cursor: project rule

.cursor/rules/placeholder-shipped-as-done.mdc
---
description: "AgentFails: A stub shipped as 'done'"
alwaysApply: true
---

## No placeholders in "done" work
- Never report a task complete while any changed code contains `pass`, `TODO`, `FIXME`,
  `not implemented`, or a hard-coded return standing in for real logic.
- If you cannot finish a part, say so in the first line of your reply and list exactly what is stubbed.
- Before saying done, search the diff: `git diff | grep -nE "TODO|FIXME|not implemented|pass$"`.
CI / script

CI step: fail if the diff adds placeholders

.github/workflows/no-placeholders.yml
name: no-placeholders
on: pull_request
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }
      - name: Fail on new placeholders
        run: |
          if git diff "origin/${{ github.base_ref }}...HEAD" -U0 | grep -E '^\+' \
             | grep -nE 'TODO|FIXME|not implemented|NotImplementedError|^\+\s*pass\s*$'; then
            echo "Placeholder code added. Finish it or open a tracked issue."; exit 1
          fi
Skill

Shared /verify skill for Claude Code

Commit it to the repo so the whole team (and every agent session) runs the same checks. Replace the commands with your project's real ones.

.claude/skills/verify/SKILL.md
---
name: verify
description: Verify the current change before calling it done. Use before every commit, PR, or "done" message.
---

# Verify

Run every step and paste the real output. Never summarize a step you did not run.

1. **Scope**: run `git diff --stat` and `git status --short`. For every changed file, say which part
   of the request needs it. Any file you cannot justify gets reverted, or listed under
   "Unrequested changes" for the user to decide.
2. **Build and types**: `npm run build` (or the project's build command).
3. **Tests**: `npm test`. Report pass/fail counts. If a test was edited, skipped or deleted,
   say so explicitly with the reason.
4. **Behavior**: exercise the changed behavior once for real (a curl, a CLI run, a screenshot)
   and show what happened.
5. **Report** in this format:
   - Requested: <one line>
   - Changed files: <list, each with its reason>
   - Checks run: <command -> result>
   - Not done / unsure: <list, or "none">

Sources and credit

Related patterns

翻车 of the week

One real agent failure and its fix, every week. Free, short, no spam.