micro/go-micro · error

agent run %s input state decode: %w

Error message

agent run %s input state decode: %w

What it means

The paused run's State (an inputPause payload holding the original message) is decoded with run.State.Scan; if that JSON decode fails, resumeInput wraps the error. It indicates the stored input-pause state is corrupt, empty, or written in an incompatible format (e.g. by an older library version).

Source

Thrown at agent/checkpoint.go:143

}

func (a *agentImpl) resumeInput(ctx context.Context, runID, input string) (*Response, error) {
	if a.opts.Checkpoint == nil {
		return nil, fmt.Errorf("agent %s has no checkpoint configured", a.opts.Name)
	}
	run, ok, err := a.opts.Checkpoint.Load(ctx, runID)
	if err != nil {
		return nil, err
	}
	if !ok {
		return nil, fmt.Errorf("agent run %s not found", runID)
	}
	if run.Status != "paused" || run.State.Stage != agentInputStep {
		return nil, fmt.Errorf("agent run %s is not waiting for human input", runID)
	}
	var p inputPause
	if err := run.State.Scan(&p); err != nil {
		return nil, fmt.Errorf("agent run %s input state decode: %w", runID, err)
	}
	message := p.OriginalMessage
	if message == "" {
		message = string(run.State.Data)
	}
	message += "\n\nHuman input: " + input
	run.Status = "running"
	run.State.Stage = agentAskStep
	run.State.Data = []byte(message)
	a.mu.Lock()
	defer a.mu.Unlock()
	if a.model == nil {
		a.setup()
	}
	return a.askLocked(ctx, run.ID, message, run.ParentID, &run, true)
}

func (a *agentImpl) pending(ctx context.Context) ([]flow.Run, error) {

View on GitHub (pinned to 24529f1404)

Solutions

  1. Discard the corrupt checkpoint entry and start a new agent run with the original message plus the human input.
  2. Log the wrapped json error to identify the exact field/type mismatch; migrate old records if upgrading versions.
  3. Verify the checkpoint store preserves payloads byte-for-byte (round-trip test).
  4. Fall back to the raw State.Data as the message when OriginalMessage is empty (the library already does this for blank, not malformed, data).

Example fix

// before
resp, err := agent.ResumeInput(ctx, ag, runID, input) // corrupt old-format state
// after
if err != nil && strings.Contains(err.Error(), "input state decode") {
    ckpt.Delete(ctx, runID)
    resp, err = ag.Run(ctx, originalMsg + "\n\nHuman input: " + input)
}
Defensive patterns

Strategy: try-catch

Validate before calling

run, ok, _ := ckpt.Load(ctx, runID)
if ok {
    var p inputPauseProbe
    if err := run.State.Scan(&p); err != nil { /* corrupt */ }
}

Try / catch

resp, err := agent.ResumeInput(ctx, ag, runID, input)
if err != nil && strings.Contains(err.Error(), "input state decode") {
    ckpt.Delete(ctx, runID)
    resp, err = ag.Run(ctx, originalMessage + "\n\nHuman input: " + input)
}

Prevention

When it happens

Trigger: Checkpoint data for a request_input pause was truncated/corrupted, written by a version whose inputPause schema differs, or the store returned bytes that don't unmarshal into inputPause.

Common situations: Library upgrades changing the inputPause struct while old checkpoints remain; manual checkpoint migration/edits; store-level encoding issues (compression, charset) corrupting payloads.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/ae48e29e33ab856d. Report an issue: GitHub.