fix(run): propagate the Actor's non-zero exit code#1195
Open
l2ysho wants to merge 2 commits into
Open
Conversation
The catch block wrapping execWithLog read stderr but never set process.exitCode or re-threw, so a failing Actor made the CLI exit 0. The command framework's `exitCode ||= 1` never fired because the error was swallowed here. This silently broke CI/shell chains like `apify run && deploy`. Forward the child's exit code (falling back to 1 for signal-killed children) so the CLI exits non-zero when the Actor fails. Closes #1180, #1190 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…pify-run-exits-0-when-the-actor-fails
Contributor
Author
|
@vladfrangu this issue popped up in 2 different ways so I took a look. Just do not no why it was done this way in a first place (like always swallow error), maybe there was some reason I am not aware of? also feel free to check this follow up |
patrikbraborec
approved these changes
Jun 8, 2026
vladfrangu
approved these changes
Jun 8, 2026
Comment on lines
-450
to
-454
| const { stderr } = err as ExecaError; | ||
|
|
||
| if (stderr) { | ||
| // TODO: maybe throw in helpful tips for debugging issues (missing scripts, trying to start a ts file with old node, etc) | ||
| } |
Member
There was a problem hiding this comment.
I wouldn't remove the old code with the cast but ik we had some ideas to inspect the stderr output and give hints. Idk why we never propagated the exitCode tho 😅
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
apify runexited with code0even when the Actor failed. Thecatchblock wrappingexecWithLoginRunCommandreadstderrbut never setprocess.exitCodeor re-threw (it held only aTODO), so the error was swallowed and the command framework'sprocess.exitCode ||= 1never fired.This silently broke CI and shell chains like
apify run && deploy— a failing Actor looked successful to any caller inspecting the exit code.Fixes #1190
Fixes #1180
Change
In the
catchblock, forward the child's exit code:process.exit(10)→ CLI exits10).1for signal-killed children, whereExecaError.exitCodeisundefined.execWithLogalready prints the message and the Actor's own stdout/stderr is inherited regardless. Only the exit code was being lost.Tests
Added a scenario test (
test/local/__fixtures__/commands/run/javascript/propagates-non-zero-exit-code.test.ts) following the existing fixture convention: it scaffolds aproject_emptyActor, copies in a failingmain.jsfixture that exits10, runs it, and asserts the CLI'sprocess.exitCodeis10.Verified TDD red → green, plus end-to-end with the built CLI:
0❌10✅lint,format,build, andtest:localall pass; existingruntests unaffected.Follow-up
Exit-code handling for
execWithLogchildren is inconsistent across commands (run.ts,create.ts,upgrade.tseach differ), andexec.tsdiscards the friendly error it builds. Tracked in #1196 — out of scope for this fix.