alibaba/open-code-review · error

resume rejected: input mode changed from %q to %q; %s

Error message

resume rejected: input mode changed from %q to %q; %s

What it means

validateInputIdentity rejects resuming when the input mode recorded in the manifest differs from the current request's mode. Mode feeds item_id derivation, so parent and child items cannot even be aligned side by side — resuming across modes would corrupt reuse of prior results.

Source

Thrown at internal/session/resume_identity.go:110

		// looking for a crash that never happened. A session_end with no manifest
		// is a session older than run manifests, or a run that failed before
		// freezing one.
		return fmt.Errorf("resume session %q closed without a run manifest, so its input identity cannot be verified — it either predates run manifests or failed before recording one; %s", s.SessionID, resumeHint)
	case m.SchemaVersion != ManifestSchemaVersion:
		return fmt.Errorf("resume session %q carries manifest schema %q, but this build can only verify %q; %s", s.SessionID, m.SchemaVersion, ManifestSchemaVersion, resumeHint)
	case m.Operation != OperationReview:
		return fmt.Errorf("resume session %q recorded operation %q, not %q; %s", s.SessionID, m.Operation, OperationReview, resumeHint)
	case len(m.Coverage.Selected) == 0:
		// Without this, an empty parent and an empty child would both hash to the
		// canonical empty digest, pass every comparison, and produce a run that
		// reuses nothing and dispatches nothing.
		return fmt.Errorf("resume session %q selected no input, so it has nothing to resume; %s", s.SessionID, resumeHint)
	}

	if m.Input.Mode != id.Mode {
		// Mode feeds item_id derivation, so parent and child items cannot even be
		// put side by side.
		return fmt.Errorf("resume rejected: input mode changed from %q to %q; %s", m.Input.Mode, id.Mode, resumeHint)
	}
	// Both sides empty means a repository with no remote, which is unchanged.
	if m.Repository.IdentitySHA256 != id.RepositorySHA256 {
		return fmt.Errorf("resume rejected: repository identity changed, so this is not the repository the parent run reviewed; %s", resumeHint)
	}
	if m.Input.SourceArtifactSHA256 != id.SourceArtifactSHA256 {
		return fmt.Errorf("resume rejected: the reviewed input changed since session %q — a ref may now point at a different commit, or the selected file set changed; %s", s.SessionID, resumeHint)
	}
	if m.Execution.RuleConfigSHA256 == "" {
		return fmt.Errorf("resume session %q recorded no rule identity, so it cannot be verified against the current rules; %s", s.SessionID, resumeHint)
	}
	if m.Execution.RuleConfigSHA256 != id.RuleConfigSHA256 {
		// The digest is one aggregate, so it can only be attributed to a layer,
		// never to a specific rule or pattern.
		return fmt.Errorf("resume rejected: review rule identity changed — either a rule text layer (custom, project, global or system) or the include/exclude file filter differs from session %q; %s", s.SessionID, resumeHint)
	}
	return nil
}

View on GitHub (pinned to 5cf97d0d15)

Solutions

  1. Re-run resume with the same mode used by the parent session (check the session manifest/config)
  2. Start a new review under the new mode instead of resuming
  3. Update the config/flags so the mode matches the parent run

Example fix

// before
ocr review --resume abc123 --mode files   # parent used ref mode
// after
ocr review --resume abc123 --mode ref     # match parent mode
Defensive patterns

Strategy: validation

Validate before calling

// Match the parent session's input mode before resuming
if sess.Manifest != nil && sess.Manifest.Input.Mode != currentRequestMode {
    return fmt.Errorf("parent used mode %q; re-run with that mode or start fresh",
        sess.Manifest.Input.Mode)
}

Type guard

func modeMatches(m *session.Manifest, want string) bool {
    return m != nil && m.Input.Mode == want
}

Try / catch

if err := ValidateResume(s, req); err != nil {
    if strings.Contains(err.Error(), "input mode changed") {
        return startNewReview(req) // mode changes require a fresh run
    }
    return err
}

Prevention

When it happens

Trigger: ValidateResume where m.Input.Mode != id.Mode — e.g. the parent run used one review input mode (such as a diff/ref mode) and the resume request selected a different mode (file-set vs ref).

Common situations: User changes the review mode flag or config default between the original run and the resume; running resume from a different context (local vs CI) where a different mode is the default.

Related errors


AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02). Data as JSON: /api/errors/d509d08abb673471. Report an issue: GitHub.