Skip to content

fix(replybot): clear stale error/wait/retries on state transitions#136

Open
nandanrao wants to merge 1 commit into
mainfrom
feature/state-cleanup-transient-fields
Open

fix(replybot): clear stale error/wait/retries on state transitions#136
nandanrao wants to merge 1 commit into
mainfrom
feature/state-cleanup-transient-fields

Conversation

@nandanrao

Copy link
Copy Markdown
Contributor

Problem

Transient fields (error, wait, waitStart, retries) were leaking into states where they no longer apply. For example:

  • A participant in WAIT_EXTERNAL_EVENT that received a MACHINE_REPORT error would keep the stale wait object in the new ERROR state
  • END and QOUT transitions retained error/retry context from prior states
  • RESPOND_AGAIN (REDO) retained stale error when Dean retried a failed participant

This is visible to users via the Monitor tab's raw state_json viewer and pollutes the error_tag/fb_error_code computed columns used by StatesList filtering.

Solution

Enforce an invariant in apply(): transient fields exist only in their owning states:

  • errorERROR, BLOCKED
  • wait / waitStartWAIT_EXTERNAL_EVENT
  • retriesRESPONDING, ERROR, BLOCKED (Dean retry-eligible states)

Changes to apply() (8 cases)

Case Clears Keeps
RESPOND + wait, waitStart (error+retries already cleared)
RESPOND_AGAIN (REDO) error, wait retries — Dean's max-attempts backoff guard
WAIT_RESPONSE (QOUT) error, retries
HANDOFF error, retries wait (being set)
WAIT_EXTERNAL_EVENT error, retries wait (being set)
END error, wait, retries
BLOCKED wait, waitStart error (being set), retries
ERROR wait, waitStart error (being set), retries

Dean safety

Dean's queries always pair current_state with the tag/code filter (e.g. current_state = 'ERROR' AND error_tag = ANY(...)), so it already self-gates. The retries field is preserved in RESPOND_AGAIN so Dean's max-attempts guard (JSON_ARRAY_LENGTH(state_json->'retries') < N) continues to work.

Testing

  • 6 new logs-based tests using getState(log) — each exercises a real reachable transition
  • 1 existing test updated: "Responds while waiting with response and repeats with old waitstart" was asserting on the stale waitStart leak (5 from a prior wait). Renamed and updated to assert fresh waitStart (10 from the new echo).
  • 351 passing, 0 failing, 1 pending (baseline: 345 passing)
  • No new lint errors introduced

Rollout plan

  1. This PR (Layer A) — deploy replybot, soak for a few days. New transitions produce clean state_json.
  2. Layer D (follow-up) — one-time SQL backfill to strip stale error/wait/retries from existing rows. This also recomputes the stored computed columns (error_tag, fb_error_code, timeout_date, next_retry). To be done after confirming A is stable in production.

Transient fields (error, wait, waitStart, retries) were leaking into
states where they no longer apply. For example, a participant in
WAIT_EXTERNAL_EVENT that received a MACHINE_REPORT error would keep
the stale wait object in the new ERROR state. Similarly, END and QOUT
transitions retained error/retry context from prior states.

This is visible to users via the Monitor tab's raw state_json viewer
and pollutes the error_tag/fb_error_code computed columns used by
StatesList filtering.

Changes to apply():
- RESPOND: also clear wait/waitStart (already cleared error/retries)
- RESPOND_AGAIN (REDO): clear error/wait, keep retries for Dean backoff
- WAIT_RESPONSE (QOUT): clear error/retries
- HANDOFF: clear error/retries
- WAIT_EXTERNAL_EVENT: clear error/retries
- END: clear error/wait/retries
- BLOCKED: clear wait/waitStart (keep error/retries)
- ERROR: clear wait/waitStart (keep error/retries)

Invariant enforced: transient fields exist only in their owning states
- error: ERROR, BLOCKED
- wait/waitStart: WAIT_EXTERNAL_EVENT
- retries: RESPONDING, ERROR, BLOCKED

Added 6 logs-based tests covering real reachable transitions.
Updated 1 existing test that was asserting on the stale waitStart leak.
@netlify

netlify Bot commented Jul 8, 2026

Copy link
Copy Markdown

Deploy Preview for vlab-research canceled.

Name Link
🔨 Latest commit 0ec3bf9
🔍 Latest deploy log https://app.netlify.com/projects/vlab-research/deploys/6a4e58b97c118d000853da88

@netlify

netlify Bot commented Jul 8, 2026

Copy link
Copy Markdown

Deploy Preview for virtuallab-videos canceled.

Name Link
🔨 Latest commit 0ec3bf9
🔍 Latest deploy log https://app.netlify.com/projects/virtuallab-videos/deploys/6a4e58b92ee1fe000808c048

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