Skip to content

fix: name the real reason a session failed, and record it - #179

Merged
mohammadp1001 merged 1 commit into
mainfrom
fix/honest-session-failure-status
Aug 13, 2026
Merged

fix: name the real reason a session failed, and record it#179
mohammadp1001 merged 1 commit into
mainfrom
fix/honest-session-failure-status

Conversation

@mohammadp1001

Copy link
Copy Markdown
Owner

The problem

Two sessions in the 2026-08-13 live run (run-4) failed, for two completely
unrelated reasons, and both were recorded under a status naming a third thing that
never happened:

Session Real cause Recorded as
run-4/session-0014 main_agent reply was not JSON SKIPPED_DATA_UNAVAILABLE
run-4/session-0019 Vertex AI 429 RESOURCE_EXHAUSTED SKIPPED_DATA_UNAVAILABLE

Market data was fine in both cases. Worse, the warnings column held only the
FR-005 feedback-block notes and a restatement of the status - the actual exception
text appeared nowhere in the memory bank, only on stdout. Anyone reading the
bank later would go check Alpaca for an outage that never happened.

The fix

  • SKIPPED_AGENT_ERROR is a new status for a failure inside the agent: an
    unparseable reply, or no reply at all because the provider refused.
    SKIPPED_DATA_UNAVAILABLE now means only what its name says.
  • The exception text is persisted to the session's warnings as Cause: ...,
    so a post-mortem can read the real reason out of the bank alone.

This is the same distinction _handle_overrun_candles already draws for
SKIPPED_OVERRUN - three different problems with three different fixes, and filing
one as another sends you to the wrong system.

Why SessionSkip rather than a second return value

_run_investigation used to return a bare status string. Status and cause now
travel together in a frozen SessionSkip(status, detail), because keeping the two
apart is exactly how they drifted: the status said one thing and the only real
explanation went to stdout and was lost.

Not in scope

The 429 itself deserves backoff, and the root cause of session-0014's unparseable
reply still needs the captured OTel bytes. Both are noted in the handoff as
follow-ups. This PR only stops the bank from lying about which of them happened.

Verification

  • ruff check alphoryn/ tests/ clean
  • 703 tests, 100% coverage (scheduler.py 299 stmts / 84 branches, all covered)
  • Reproduced the CI environment: GOOGLE_APPLICATION_CREDENTIALS=/nonexistent/adc.json python -m pytest -q

Two sessions in the 2026-08-13 live run failed for two unrelated reasons and
both were filed as SKIPPED_DATA_UNAVAILABLE:

  session-0014  main_agent reply was not JSON
  session-0019  Vertex AI 429 RESOURCE_EXHAUSTED

Market data was fine in both cases. The exception text existed only on stdout,
so anyone reading the memory bank afterwards would go and check Alpaca for an
outage that never happened.

An agent that was reached and gave an unusable answer is now SKIPPED_AGENT_ERROR,
and SKIPPED_DATA_UNAVAILABLE means only what its name says. This is the same
distinction _handle_overrun_candles already draws for SKIPPED_OVERRUN.

The cause travels with the status as SessionSkip(status, detail) rather than a
bare string, because keeping them apart is how they drifted in the first place.
The detail is persisted to the session's warnings, so a post-mortem can read the
real cause out of the bank alone.
@mohammadp1001
mohammadp1001 merged commit b9713f1 into main Aug 13, 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.

1 participant