Bitbucket "after-script" Not Running or Masking Failures
after-script runs after the main script whether it passed or failed - useful for cleanup and reporting. Its own exit code does not fail the step, which surprises teams who put real assertions there.
What this error means
Cleanup or reporting placed in after-script does not behave as expected: a failing command there does not fail the build, or commands are missing context because the step already failed. The main result is decided by script, not after-script.
script:
- ./run-tests.sh
after-script:
- ./upload-coverage.sh # runs even if tests failed; its exit code is ignoredCommon causes
Expecting after-script to affect the step result
after-script is for teardown. A non-zero exit there does not turn a passing step red, so assertions placed there never gate the build.
Assuming after-script is skipped on failure
It runs after the main script regardless of pass/fail. Cleanup written assuming success may hit a half-finished state from a failed script.
How to fix it
Use after-script only for cleanup and reporting
Keep teardown idempotent and tolerant of a failed main script. Use BITBUCKET_EXIT_CODE to branch on the result.
script:
- ./run-tests.sh
after-script:
- if [ "$BITBUCKET_EXIT_CODE" != "0" ]; then ./collect-logs.sh; fi
- ./teardown.sh || trueKeep real assertions in the main script
- Move any check that must fail the build into
script, notafter-script. - Treat
after-scriptas best-effort cleanup that cannot fail the step. - Use
BITBUCKET_EXIT_CODEinsideafter-scriptto react to the result.
How to prevent it
- Put pass/fail logic in
script; put cleanup inafter-script. - Make
after-scripttolerant of a failed main script. - Read
BITBUCKET_EXIT_CODEto know whether the step passed.