Skip to content

Worker exit code 3 is called an import failure only when the worker said so on stderr - #124

Merged
guijacquemet merged 2 commits into
mainfrom
claude/worker-exit-3-needs-import-marker
Oct 13, 2026
Merged

guijacquemet merged 2 commits into
mainfrom
claude/worker-exit-3-needs-import-marker

Conversation

@guijacquemet

Copy link
Copy Markdown
Contributor

Problem

log.hint_for_exit maps exit code 3 to "the app's tool module failed to import". Code 3 is not unique: the Windows C runtime ends a process with 3 when SIGSEGV is only raised (faulthandler._sigsegv(), what the Playground's stress_crash did), so a native crash on Windows was reported as an import failure (sandbox defect D4).

Evidence, run https://github.com/CellMigrationLab/LabConstrictor-Tools/actions/runs/38383005811 (job D4, Python 3.12):

  • windows-latest, faulthandler._sigsegv() in a worker: worker exited unexpectedly (code 3): the app's tool module failed to import (see the traceback above)
  • windows-latest, faulthandler._read_null() (real access violation): code 3221225477 ... crashed natively
  • ubuntu-latest / macos-15: code -11 ... crashed natively for both.

Change (smallest correct fix, no protocol change)

The hint for code 3 now also requires the marker worker.py prints as its last stderr line right before SystemExit(3) (cannot import tool module, now log.IMPORT_FAILED_MARKER). The message still shows the real exit code and the worker's output; only the likely-cause sentence changes. docs/HOST_PARITY.md proposal worker_exit_hints.import_failed gets stderr_contains to match. An import error that raises ImportError still gets the first rule ("a Python package is missing or broken") as before.

Effect on conformance / RUN cases

None: conformance.json has no case that reads a worker exit hint (only exit_code: 0 entries for CLI runs), and stress_crash expects only status: CRASHED. Other hosts (Napari uses this code; QuPath and Fiji have their own copies, see HOST_PARITY I04/QP-13) keep their current behaviour until they copy the rule; the parity table is a proposal, not a decision.

Companion: LabConstrictor-Playground stress.crash() stops using _sigsegv so it no longer exits with 3 on Windows.

New test in tests/test_logging.py: code 3 with the marker gives the import hint, code 3 without it gives none.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Y2SN8SuEakTdiWy3F2WUqN


Generated by Claude Code

… worker said so on stderr

Windows ends a process with exit code 3 for abort() and for a raised SIGSEGV (faulthandler._sigsegv), so a native crash there was reported as an import failure. The hint now also requires the marker worker.py prints just before exiting with 3. The message still shows the real exit code; no protocol or conformance case changes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2SN8SuEakTdiWy3F2WUqN
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2SN8SuEakTdiWy3F2WUqN
@guijacquemet
guijacquemet merged commit 738bf1c into main Oct 13, 2026
6 checks passed
guijacquemet added a commit that referenced this pull request Oct 13, 2026
…test hygiene, CI hardening (#129)

* Audit fixes before the alpha: say why a big TIFF was not mapped, ledger, docs, test hygiene

- convert._memmap_tiff: a TIFF of 8 MiB or more that is read the plain way logs one warning (file, reason) to the log and the worker's stderr
- worker._orphan_exit: a temp folder that cannot be removed is logged
- ledger rows for #124 and #125, real PR numbers instead of "this PR", pending section replaced by a note
- docs: tag install URLs, OPERATIONS contradictions, HOST_FEATURES rows, Playground rule, features rule exception
- tests: new tests and sabotage rows, dead retention guard removed, gc test asserts, test count not hard-coded

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2SN8SuEakTdiWy3F2WUqN

* CI hardening: pin the third-party action by SHA, release_sandbox takes Fiji and QuPath refs as inputs

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2SN8SuEakTdiWy3F2WUqN

* Ledger row for the told TIFF fallback

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y2SN8SuEakTdiWy3F2WUqN

---------

Co-authored-by: Claude <noreply@anthropic.com>
@guijacquemet
guijacquemet deleted the claude/worker-exit-3-needs-import-marker branch October 14, 2026 16:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants