Skip to content

Commit beca428

Browse files
committed
Fix checkpoint-miss-on-resume silently falling through to a fresh run with an undefined task; throw a clear, distinct error instead
1 parent 135543f commit beca428

1 file changed

Lines changed: 17 additions & 2 deletions

File tree

connectors/gemini/delegate.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -815,9 +815,24 @@ export async function runInvestigation({ task, max_steps = 6, resume_run_id }) {
815815
// before this field existed won't have it; fall back to whatever the
816816
// caller passed (may be undefined) rather than erroring.
817817
effectiveTask = checkpoint.task || task;
818+
} else if (resume_run_id) {
819+
// A resume WAS requested but its checkpoint didn't load -- expired past
820+
// the 1-hour TTL, Redis unavailable (checkpoint.js is deliberately
821+
// fail-open, see its header), or an invalid/typo'd runId. This must
822+
// NEVER be silently treated as "no resume was requested" and fall
823+
// through to a fresh run: that previously produced a conversation
824+
// seeded with `Task: undefined` (task is genuinely ignored on a live
825+
// resume, so callers legitimately omit it), and the model burned several
826+
// steps hunting blind for context instead of investigating (found via
827+
// the 2026-07-26 checkpoint-miss test). Fail loudly and distinctly
828+
// instead, so the caller can tell "your resume target is gone" apart
829+
// from any other failure and decide whether to retry with a task.
830+
throw new Error(
831+
`resume_run_id "${resume_run_id}" has no live checkpoint -- it may have expired (1 hour TTL), Redis may be unavailable, or the id may be wrong. ` +
832+
`There is no saved task to resume from. Start a new investigation by calling again with a task and no resume_run_id.`
833+
);
818834
} else {
819-
// Either no resume_run_id was given, or the checkpoint had already
820-
// expired/wasn't found -- start a fresh run either way. Requires a real
835+
// No resume_run_id was given -- start a fresh run. Requires a real
821836
// `task` (the caller-facing tool in tools.js already guards against a
822837
// missing task on a non-resumable call, so `task` is trustworthy here).
823838
runId = randomUUID();

0 commit comments

Comments
 (0)