Skip to content

fix(capabilities): thread experiment_id through is_stale - #1280

Open
stateofkate wants to merge 1 commit into
stagingfrom
fix/capabilities-is-stale-experiment-id
Open

fix(capabilities): thread experiment_id through is_stale#1280
stateofkate wants to merge 1 commit into
stagingfrom
fix/capabilities-is-stale-experiment-id

Conversation

@stateofkate

Copy link
Copy Markdown
Collaborator

The bug

_load_fresh_analysis forwards experiment_id to is_stale, which has no such
parameter:

api/services/agent_capabilities.py:550  is_stale(..., experiment_id=experiment_id)
api/services/agent_capabilities.py:465  def is_stale(*, current_hash, schema_version, task_version_id)

The call is guarded by row is not None, so it only fires on a cache hit
which is why nothing caught it. load_stored_analysis uses stale_reason
directly and is unaffected, so the read paths look fine; the damage is confined
to get_or_generate_analysis, i.e. the durable analyzer job.

Consequence: a task version that already carries a stored comparison can never
regenerate. The job dies on TypeError for all six attempts, and because
enqueue_analysis only treats QUEUED/RUNNING/RETRYING/BLOCKED as active, the
next 3-second poll enqueues a fresh job — which fails the same way. The pane
has no error state for this, so it renders data === null as an indefinite
"Analyzing agent behavior across successful and failing runs…" spinner while
burning six attempts per cycle.

Observed in prod (worker_jobs, mode agent_capabilities):

task version jobs status
scarf-cargotracker-quarkus-to-spring-migration v2 4 consecutive FAILED, attempts=6, TypeError: is_stale() got an unexpected keyword argument 'experiment_id'
scarf-cargotracker-jakarta-to-spring-migration v2 1 same
05-F3-poison-message-recurrence v23 1 same

The fix

Give is_stale the experiment_id parameter and forward it to stale_reason,
which already understands it. Scope becomes part of freshness for the boolean
helper too, matching what stale_reason has done since #1240.

Tests

Three new tests exercise _load_fresh_analysis against a session that returns a
stored block, the half every existing cache-lookup test stubbed out as None:

  • an experiment-scoped hit is served
  • an unscoped hit is served
  • a block from another experiment is rejected rather than served

All three fail on staging with the TypeError above and pass here.

46 passed, 1 failed

The one failure, test_summary_warmup_regenerates_truthy_stale_xai_summary, is
pre-existing on staging (verified on a clean checkout of 005002b) and
untouched by this change.

_load_fresh_analysis passes experiment_id to is_stale, which does not
accept it, so every cache lookup that finds a stored block raises
TypeError. The durable analyzer job burns all six attempts on it and the
next poll enqueues a fresh one, so a task version that already carries a
comparison can never regenerate -- the pane polls forever and renders it
as an indefinite 'Analyzing agent behavior...' spinner.

Seen in prod on scarf-cargotracker-quarkus-to-spring-migration v2 (four
consecutive FAILED jobs, six attempts each) and 05-F3-poison-message-
recurrence v23.

The cache-lookup tests all stubbed the row out as None, which returns
before the freshness comparison, so nothing covered the hit path.
@vercel

vercel Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
oddish-app Ready Ready Preview Aug 18, 2026 12:02am

@github-actions

Copy link
Copy Markdown
Contributor

Oddish preview

Commit: f8caa56f28b1b5a4458e29678d91e6d91da40770

Surface Link Target
Frontend https://pr-1280.oddish.app Vercel preview for f8caa56
Backend oddish-pr-1280 oddish-pr-1280
Database project eqszvekwckbqaodfnuzl project eqszvekwckbqaodfnuzl

Vercel deployment URL: https://oddish-98w069qpg.oddish.app

Plan:

  • Frontend deploy: true
  • Backend deploy: true
  • Migrations: false

This comment is updated by the PR Preview workflow.

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