The Agent Edits a Generated File That Gets Overwritten on the Next Build
Quick answer: If a file is produced by a generator, any hand edit inside it is borrowed time. The next build rewrites the file from its source of truth and the edit vanishes, often silently, leaving a bug that was "fixed" twice. The first thing an AI agent should identify before touching a file is whether it is generated — a header comment, a build output directory, or a codegen step in the package scripts. The correct fix almost always goes into the generator's input (a template, a schema, an OpenAPI document), not into the artifact it emits.
This failure shows up in a very specific, frustrating sequence. The agent opens a generated client or a compiled type, sees the wrong field or a missing header, and edits the output directly. The tests pass locally because the edited file is on disk. Then CI runs a clean install, the generator regenerates the file, and the change is gone. The team is left staring at a fix that clearly exists in the commit history but no longer works. The root cause is not the agent's logic; it is that it never distinguished source from artifact.
How to tell a file is generated
Three signals are usually enough, and the agent should check before editing rather than after a regression.
| Signal | Where to look | What it means |
|---|---|---|
| Header comment | Top of the file | "Do not edit, generated by X" |
| Output path | generated/, dist/, build/ | Directory recreated on build |
| Codegen script | package.json scripts | A command that emits the file |
| Gitignore | .gitignore | Artifact may not even be committed |
Fix the input, not the output
For an OpenAPI-generated client, the wrong field name or type is corrected in the spec, and the client is regenerated so every consumer gets the same fix. Editing the emitted TypeScript would only patch one copy and diverge from the contract.
# the spec is the source of truth; regenerate, never hand-edit the client
# openapi.yaml
components:
schemas:
Order:
properties:
totalAmount: # corrected here
type: string
description: Amount in decimal, currency in ISO 4217
example: "49.99"
# then regenerate the client
npm run generate:client
The same rule applies to templates, migrations produced by a tool, and compiled CSS. If the artifact can be recreated from an input, the input is the only place a durable change exists.
Make the trap impossible to fall into
Two guardrails keep agents and humans from repeating the mistake. First, keep generated output in a clearly named directory and add a generated header so the file announces itself. Second, verify in CI that the committed artifact matches what the generator produces, so a direct edit fails the build instead of quietly shipping.
# regenerate into a temp dir and diff against what is committed;
# a hand edit shows up as a diff and fails CI before it can mislead anyone
npm run generate:client -- --output /tmp/gen-check
diff -r /tmp/gen-check ./src/generated && echo "generated output is in sync"
When a generated artifact is also committed, this drift check is what turns a silent overwrite into a loud, early failure. It is cheap to add and removes an entire class of "the fix disappeared" bugs.
Frequently asked questions
What if I need a one-off change faster than a regeneration?
Still change the source and regenerate; a shortcut edit will be erased and costs more the second time. If the generator cannot express what you need, extend the template or generator rather than patching the output.
Should generated files be committed at all?
If downstream consumers need them without running the build, commit them but add the CI drift check. If every environment regenerates, gitignore them and keep only the source, which eliminates the edit trap entirely.
How do I stop an agent from editing generated files?
Make generated status obvious with headers and directory names, and give the agent the codegen command in its instructions. A drift check in CI is the backstop that catches a direct edit regardless of how it got there.
Does this apply to lockfiles and snapshots too?
Lockfiles are generated but updated through the package manager, not by hand, and test snapshots are updated through the runner's update flag. The principle is identical: use the tool that owns the artifact rather than editing the artifact directly.
This is part of the AI Coding Agent Guide — start there for the full picture of keeping AI-generated changes honest.