{"record":{"id":"e0417bb638bf43bb","repo":"micro/go-micro","slug":"agent-run-s-is-terminal-with-status-q","errorCode":null,"errorMessage":"agent run %s is terminal with status %q","messagePattern":"agent run (.+?) is terminal with status %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/checkpoint.go","lineNumber":104,"sourceCode":"\tif !ok {\n\t\treturn nil, fmt.Errorf(\"agent run %s not found\", runID)\n\t}\n\tif run.Status == \"paused\" {\n\t\tif run.State.Stage == agentInputStep {\n\t\t\treturn nil, fmt.Errorf(\"agent run %s is input-required; resume with ResumeInput\", runID)\n\t\t}\n\t\trun.Status = \"running\"\n\t\trun.State.Stage = agentAskStep\n\t}\n\tif run.Status == \"done\" {\n\t\tvar resp Response\n\t\tif err := json.Unmarshal(run.State.Data, &resp); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"agent run %s response decode: %w\", runID, err)\n\t\t}\n\t\treturn &resp, nil\n\t}\n\tif terminalAgentRunStatus(run.Status) {\n\t\treturn nil, fmt.Errorf(\"agent run %s is terminal with status %q\", runID, run.Status)\n\t}\n\tmessage := string(run.State.Data)\n\tparentID := run.ParentID\n\ta.mu.Lock()\n\tdefer a.mu.Unlock()\n\tif a.model == nil {\n\t\ta.setup()\n\t}\n\treturn a.askLocked(ctx, run.ID, message, parentID, &run, false)\n}\n\n// ResumeInput resumes a checkpointed agent run that paused via the built-in\n// request_input tool. The supplied input is appended to the original request so\n// the same run can continue with durable checkpoint and completed tool history.\nfunc ResumeInput(ctx context.Context, ag Agent, runID, input string) (*Response, error) {\n\ta, ok := ag.(*agentImpl)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"agent resume input: unsupported agent implementation %T\", ag)","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/agent/checkpoint.go#L86-L122","documentation":"agent.Resume refuses to continue runs already in a terminal state (e.g. \"failed\", \"canceled\") other than \"done\". Terminal runs have concluded and cannot be re-executed; the error includes the actual status so the caller can decide what to do. Only non-terminal (running/paused in resumable stages) or done runs are resumable.","triggerScenarios":"Calling agent.Resume with a runID whose checkpointed run has a terminal status such as \"failed\" or \"canceled\", as checked by terminalAgentRunStatus.","commonSituations":"Replaying old run IDs from an incident or migration; a scheduler retrying resumes for runs that were canceled by another component; double-processing in queues where the run already failed permanently.","solutions":["Do not resume; treat the run as finished and start a new agent run with the original or amended message.","Check the run's status in the checkpoint store before calling Resume and skip terminal runs in retry loops.","If the run failed transiently, create a fresh run (new runID) rather than resuming the failed one."],"exampleFix":"// before\nresp, err := agent.Resume(ctx, ag, runID) // status: canceled\n// after\nrun, ok, _ := ckpt.Load(ctx, runID)\nif ok && isTerminal(run.Status) {\n    runID = \"\" // start fresh\n}\nresp, err = ag.Run(ctx, message)","handlingStrategy":"validation","validationCode":"run, ok, _ := ckpt.Load(ctx, runID)\nif ok && (run.Status == \"failed\" || run.Status == \"canceled\") {\n    return fmt.Errorf(\"run %s already terminal; start a new run\", runID)\n}","typeGuard":"func isResumable(r flow.Run) bool {\n    switch r.Status {\n    case \"running\", \"paused\", \"\":\n        return r.Status != \"paused\" || r.State.Stage != \"input-required\"\n    default:\n        return false\n    }\n}","tryCatchPattern":"resp, err := agent.Resume(ctx, ag, runID)\nif err != nil && strings.Contains(err.Error(), \"is terminal\") {\n    // mark job permanently failed; do not retry\n}","preventionTips":["Filter out terminal runs in retry/scheduler loops.","Check status before resuming; treat terminal as final.","Start fresh runs instead of resuming failed ones."],"tags":["agent","checkpoint","terminal-status","resume"],"backgroundTag":"invalid-state-transition","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}