migration agent's tool call returned success but the migration actually failed silently - the wrapper script...
Fixes wrapper scripts that report migration success while the tool actually failed. Use it when the harness shows green but the schema never changed, or logs show an error on a passing step. Key trigger: a pipeline through tee or grep, or an unchecked subprocess call, swallowing the tool's exit code.
TL;DR
Fix the wrapper so the tool's real exit code reaches the harness. In shell wrappers add set -euo pipefail at the top and never pipe the tool through a filter without pipefail; in Python wrappers pass check equals True to subprocess.run. The migration failed but the wrapper exited 0, so the agent recorded success and moved on while nothing changed.
migration agent's tool call returned success but the migration actually failed silently - the wrapper script swallowed the exit codeSteps
Prove the swallow. Run the wrapper against a deliberately failing migration, then print the exit code right after. Expected: the exit code is 0 even though the tool's own output shows a failure. That confirms the wrapper is lying.
Find the swallowing line in the wrapper. Common culprits:
migrate_command | tee log.txt(a pipeline returns the last command's status),migrate_command || echo done,migrate_command && true, Pythonsubprocess.run(cmd)without checking the return code. Expected: you can point at the exact line that discards the failure.Fix it. Bash: put
set -euo pipefailat the top of the script so pipelines report failures. Python: usesubprocess.run(cmd, check=True)so a non-zero exit raises. Node: await the exec call and let the rejection propagate instead of catching and ignoring it. Expected: the wrapper now exits non-zero whenever the tool fails.Re-run the failing migration through the fixed wrapper. Expected: the wrapper exits non-zero and the harness marks the step failed instead of green.
Now fix the actual migration failure, re-run, and confirm the history or version table shows the new revision applied. Expected: green step AND a changed schema. Both must be true.
Use this when
- The tool reports success but the schema is unchanged.
- Logs show an error while the harness step is green.
- The wrapper pipes tool output through tee, grep, or a log filter.
- An agent keeps "completing" migrations that never land.
Not for this skill when
- The migration genuinely succeeded (verify against the history table first).
- The tool exits non-zero but the harness is configured to ignore failures (that is a harness config issue).
- The migration SQL itself fails silently inside a transaction that then commits (different problem).
Variant phrasings
- wrapper script swallowed the exit code
- migration failed but CI passed
- bash pipe hides failing exit code
- subprocess.run did not raise on migration failure
Why it happens
In bash, a pipeline's exit status is the last command's status, so alembic upgrade head | tee log.txt returns tee's 0 even when alembic fails. || true idioms and unchecked subprocess calls do the same thing. The harness trusts the wrapper's exit code, so the failure becomes invisible and the agent proceeds as if the migration landed.
Edge cases
pipefailmakes grep-in-pipeline return 1 when nothing matches. That is correct behavior, but handle it deliberately if your wrapper greps output.- Some tools exit 0 with warnings that still matter. Parse the output for error strings as a second check, not just the exit code.
- Fixing detection surfaces old failures. The first run after the fix may turn several "green" steps red. That is the fix working.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_ohhX3tpoVVuh57ISHbc3cQ