Skip to content

fix: Dockerfile never copied docs/, breaking every stage on real deploys - #31

Merged
psi16181918161phi merged 1 commit into
psi16181918161phi:mainfrom
umarakhtarqq389-commits:fix-dockerfile-missing-docs
Aug 7, 2026
Merged

fix: Dockerfile never copied docs/, breaking every stage on real deploys#31
psi16181918161phi merged 1 commit into
psi16181918161phi:mainfrom
umarakhtarqq389-commits:fix-dockerfile-missing-docs

Conversation

@umarakhtarqq389-commits

Copy link
Copy Markdown
Contributor

Why this is urgent

This is the actual bug behind the failed test run on the live Railway demo just now. Every single run failed immediately at the Research stage.

Root cause

task_specs.py reads docs/task-specs.md at runtime to load each stage's system prompt — but the Dockerfile only ever copied src/ and frontend/, never docs/. Every stage failed instantly with FileNotFoundError the moment it tried to load its own prompt.

Found this by actually testing the deployed app end to end and tracing the failure from the live Railway logs, through runs.py, into orchestrator.py, down to this exact line.

Two more bugs found in the same failure path

  1. orchestrator.py: get_task_spec() was called outside _run_stage()'s own try/except, so this failure propagated uncaught past the "running" event with no matching "error" event — the stage stayed stuck at "running" in the UI forever, even though the overall run correctly showed "error". Fixed by moving the call inside the try block.
  2. runs.py: the run-level error message was never actually persisted anywhere — only published once over SSE and then discarded. If a client's connection dropped at that exact moment (which is what happened during testing — the SSE stream was reconnecting repeatedly), the real error message was gone forever, unrecoverable via the API. Added a detail field to RunState, persisted through _finish() and load_from_disk(), included in to_dict(). The frontend already fully supports displaying it — it just never had real data to show.

Verification

  • Rebuilt the Docker image and confirmed inside the running container: docs/ is present, get_task_spec() successfully loads real spec text (previously would have raised FileNotFoundError here)
  • 142 tests passing (8 new), 100% coverage
  • ruff/mypy/bandit clean

Root cause of the first live Railway deployment failing on every single
run: task_specs.py reads docs/task-specs.md at runtime to load each
stage's system prompt, but the Dockerfile only ever copied src/ and
frontend/ — never docs/. Every stage failed immediately with
FileNotFoundError the moment it tried to load its own prompt.

Found by actually testing the deployed app end to end (not just
inspecting code) and tracing the failure from the live Railway logs
back through runs.py and orchestrator.py to this exact line.

While tracing it, found and fixed two more real bugs in the same
failure path:

1. orchestrator.py: get_task_spec() was called in _run_stage() outside
   its own try/except block, so when it failed, the exception propagated
   uncaught past the stage's "running" event with no matching "error"
   event ever emitted for that specific stage — leaving it stuck at
   "running" forever in the UI even though the overall run correctly
   showed "error". Moved the call inside the try block so any failure
   there is now reported the same way as any other stage failure.

2. runs.py: RunState never persisted the run-level error detail message
   anywhere — _finish() only set run.status, discarding the exception
   text after one transient SSE publish. If a client's connection wasn't
   live at that exact moment (e.g. a dropped/reconnecting SSE stream,
   which is what actually happened during testing), the real error
   message was gone forever with no way to retrieve it via the API
   afterward. Added a `detail` field to RunState, persisted it in
   _finish() and load_from_disk(), and included it in to_dict() — the
   frontend already had full support for displaying it, it just never
   had real data to show.

Verified the actual root-cause fix by rebuilding the Docker image and
confirming inside the running container: docs/ is present, and
get_task_spec() successfully loads real Task Specification text (it
previously would have raised FileNotFoundError here).

142 tests passing (8 new), 100% coverage, ruff/mypy/bandit clean.
@psi16181918161phi
psi16181918161phi merged commit c2d9673 into psi16181918161phi:main Aug 7, 2026
3 checks passed
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