{"record":{"id":"b61b2dc8fe874f75","repo":"micro/go-micro","slug":"agent-checkpointed-run-is-input-required-resume","errorCode":null,"errorMessage":"agent: checkpointed run is input-required; resume with ResumeInput","messagePattern":"agent: checkpointed run is input-required; resume with ResumeInput","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/stream.go","lineNumber":178,"sourceCode":"\t}\n\n\ta.mu.Lock()\n\tdefer a.mu.Unlock()\n\tif a.tools == nil {\n\t\ta.tools = ai.NewTools(a.opts.Registry, ai.ToolClient(a.opts.Client))\n\t}\n\tbase := a.toolHandler()\n\thandler := func(ctx context.Context, call ai.ToolCall) ai.ToolResult {\n\t\t_ = sendStreamEvent(ctx, events, &StreamEvent{Type: StreamEventToolStart, ToolCall: call})\n\t\tresult := base(ctx, call)\n\t\t_ = sendStreamEvent(ctx, events, &StreamEvent{Type: StreamEventToolEnd, ToolCall: call, Result: result})\n\t\treturn result\n\t}\n\ta.setupWithToolHandler(handler)\n\tdefer a.setupWithToolHandler(nil)\n\tif run.Status == \"paused\" {\n\t\tif run.State.Stage == agentInputStep {\n\t\t\treturn nil, errors.New(\"agent: checkpointed run is input-required; resume with ResumeInput\")\n\t\t}\n\t\trun.Status = \"running\"\n\t\trun.State.Stage = agentAskStep\n\t}\n\treturn a.askLocked(ctx, run.ID, string(run.State.Data), run.ParentID, &run, false)\n}\n\ntype agentStreamAdapter struct {\n\tstream AgentStream\n}\n\ntype memoryRecordingStream struct {\n\tstream ai.Stream\n\tmemory Memory\n\n\tmu     sync.Mutex\n\tchunks []string\n\tclosed bool","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/micro/go-micro/blob/24529f140421a11a33b6999ab7944f2021cfd69c/agent/stream.go#L160-L196","documentation":"The checkpointed run is paused specifically at the agentInputStep, meaning the agent is waiting for user input. Streaming resume cannot supply that input, so the caller must use ResumeInput to provide it instead.","triggerScenarios":"Calling ResumeStreamAsk/ResumeStream on a run whose checkpoint State.Stage equals agentInputStep (run.Status \"paused\" at the input step).","commonSituations":"Human-in-the-loop workflows where the agent paused for a form/confirmation and the client mistakenly resumes with the streaming API instead of submitting input; automated resumers that don't branch on pause stage.","solutions":["Call ResumeInput with the user's input to continue an input-required run","Before resuming, check the checkpoint's State.Stage and branch: agentInputStep → ResumeInput, otherwise → resume stream","Design the client so the UI that caused the pause is the one that submits input"],"exampleFix":"// before\nstream, err := agent.ResumeStreamAsk(ctx, ag, runID) // run paused for input\n// after\ninput, _ := collectUserInput()\nresp, err := agent.ResumeInput(ctx, ag, runID, input)","handlingStrategy":"validation","validationCode":"run, ok, _ := store.Load(ctx, runID)\nif ok && run.Status == \"paused\" && run.State.Stage == \"input\" {\n    return agent.ResumeInput(ctx, ag, runID, userInput)\n}","typeGuard":null,"tryCatchPattern":"stream, err := agent.ResumeStreamAsk(ctx, ag, runID)\nif err != nil && strings.Contains(err.Error(), \"input-required\") {\n    return agent.ResumeInput(ctx, ag, runID, collectInput())\n}","preventionTips":["Inspect checkpoint Stage before choosing the resume API","Route paused-for-input runs to the input submission UI path","Model run state in your orchestrator so streaming resume is never attempted on input-required runs"],"tags":["go","agent","checkpoint","human-in-the-loop","paused-run"],"backgroundTag":"invalid-state-transition","analyzedSha":"24529f140421a11a33b6999ab7944f2021cfd69c","analyzedAt":"2026-09-01T02:52:24.923Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}