Skip to content

fix: todo-continuation fires during model fallback causing retry loop #2063

@youngbinkim0

Description

@youngbinkim0

Context

Reported by @rothnic in PR #1777 — when runtime-fallback is in progress, the todo-continuation-enforcer fires on session.idle, uses the old rate-limited model, and causes a loop.

Related PR: #1777

Problem

The todo-continuation-enforcer hook monitors for idle sessions and injects continuation messages to keep work progressing. However, it has no awareness of the runtime-fallback system. When a model is rate-limited and runtime-fallback is processing:

  1. The rate-limited model request fails
  2. Runtime-fallback begins its retry/model-switch logic
  3. During the brief idle gap (while fallback resolves), session.idle fires
  4. Todo-continuation-enforcer detects incomplete todos and injects a "continue" message
  5. This "continue" message goes to the old rate-limited model (not the fallback model)
  6. That request also fails → another idle → another continuation → loop

Root Cause

  • todo-continuation-enforcer/handler.ts has no check for whether a runtime-fallback is in progress
  • todo-continuation-enforcer/constants.ts sets ABORT_WINDOW_MS = 3000 (3 seconds) — if fallback resolution takes longer than 3s, the abort window expires and continuation fires
  • todo-continuation-enforcer/idle-event.ts processes session.idle events without consulting fallback state
  • There is no shared "fallback in progress" signal between runtime-fallback and todo-continuation-enforcer

Suggested Fix

Options (not mutually exclusive):

  • Shared signal: Runtime-fallback sets a "fallback in progress" flag that todo-continuation checks before firing
  • Extended abort window: Increase ABORT_WINDOW_MS or make it dynamic based on fallback state
  • Explicit suppression: Runtime-fallback explicitly suppresses continuation hooks during retry
  • Model-aware continuation: Todo-continuation checks if the model it would use is currently rate-limited

Key Files

  • src/hooks/todo-continuation-enforcer/handler.ts — No fallback-in-progress check
  • src/hooks/todo-continuation-enforcer/idle-event.ts — Processes session.idle without consulting fallback state
  • src/hooks/todo-continuation-enforcer/constants.tsABORT_WINDOW_MS = 3000
  • src/hooks/runtime-fallback/fallback-state.ts — Fallback state management (no cross-hook signal)
  • src/hooks/runtime-fallback/event-handler.ts — Handles session events during fallback

cc @rothnic @davidakerr

Metadata

Metadata

Assignees

No one assigned

    Labels

    triage:bugConfirmed bug with repro steps

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions