alibaba/open-code-review · error
resume rejected: provider changed from %q to %q without bein
Error message
resume rejected: provider changed from %q to %q without being asked for; %s to resume across providers on purpose
What it means
ValidateResume guards `ocr review --resume` against silently resuming a session under a different LLM provider than the original run. When the stored manifest's provider differs from the request's provider and the caller did not explicitly pass --provider, resume is rejected so config drift cannot quietly change which model vendor performs the review. Passing --provider explicitly signals the switch was intentional.
Source
Thrown at internal/session/resume_identity.go:61
// every rejection.
//
// Checks run top to bottom and the first mismatch decides. Order matters at
// source_artifact vs rule_config: rule_config_sha256 is a single aggregate over
// the rule-text layers and the file filter and cannot be decomposed, so a filter
// change is reported as the input mismatch it actually caused rather than as an
// unattributable rule change.
func (s *ResumeState) ValidateResume(req ResumeRequest) error {
if s == nil {
return nil
}
if err := s.validateInputIdentity(req.Identity); err != nil {
return err
}
m := s.Manifest
providerChanged := m.Execution.Provider != req.Provider
if providerChanged && !req.ProviderExplicit {
return fmt.Errorf("resume rejected: provider changed from %q to %q without being asked for; %s to resume across providers on purpose", m.Execution.Provider, req.Provider, explicitFlagHint("--provider", req.Provider))
}
// Model is only compared within the same provider: switching provider on
// purpose necessarily brings that provider's own model with it.
if !providerChanged && m.Execution.Model != req.Model && !req.ModelExplicit {
return fmt.Errorf("resume rejected: model changed from %q to %q without being asked for; %s to resume across models on purpose", m.Execution.Model, req.Model, explicitFlagHint("--model", req.Model))
}
return nil
}
// validateInputIdentity compares only the input half of the resume contract: the
// parent manifest must be verifiable, and every input field must match. Provider
// and model are deliberately left out: those are command-line intent, not
// something derived from the input.
//
// This runs once, at admission, and is never repeated during the run: the caller
// pins the run to the commit endpoints this comparison was made against (see
// agent.SealedInput), so a second comparison could only ever confirm the first.
func (s *ResumeState) validateInputIdentity(id RunIdentity) error {View on GitHub (pinned to 5cf97d0d15)
Solutions
- Re-run with --provider <new-provider> to confirm you want to switch providers mid-session
- Restore the original provider in config/env so it matches the parent session, then resume
- Start a fresh review instead of resuming (as the resumeHint suggests)
Example fix
// before ocr review --resume abc123 # provider drifted in config // after ocr review --resume abc123 --provider anthropic # explicit switch
Defensive patterns
Strategy: validation
Validate before calling
// Check the stored session's provider before resuming
if sess.Manifest != nil && sess.Manifest.Execution.Provider != requestedProvider && !req.ProviderExplicit {
fmt.Printf("session %s used provider %q; pass --provider %q to switch deliberately\n",
sess.SessionID, sess.Manifest.Execution.Provider, requestedProvider)
} Type guard
func resumeProviderMatches(s *session.State, want string) bool {
return s != nil && s.Manifest != nil && s.Manifest.Execution.Provider == want
} Try / catch
if err := ValidateResume(s, req); err != nil {
if strings.Contains(err.Error(), "provider changed") {
req.ProviderExplicit = true // or re-run with --provider
return ValidateResume(s, req)
}
return err
} Prevention
- Pin the provider in config rather than relying on environment defaults
- Record the provider alongside the session ID when scripting resumes
- Use explicit --provider whenever you know the environment's default may differ
When it happens
Trigger: Calling ValidateResume (via `ocr review --resume <id>`) where s.Manifest.Execution.Provider differs from req.Provider while req.ProviderExplicit is false — e.g. the default provider in config changed since the parent session, or an env var like a provider key switched the effective provider.
Common situations: User upgrades open-code-review or edits config to a new default provider, then resumes an old session; CI environment has a different provider configured than the machine that started the run; user toggles between providers (e.g. openai vs anthropic) between runs.
Related errors
- load resume session: %w (run 'ocr session list' to see avail
- %w (run 'ocr session list' to see available sessions)
- resume session %q has no completed scan items (run 'ocr sess
- resume rejected: model changed from %q to %q without being a
- resume session %q recorded operation %q, not %q; %s
AI-assisted analysis of alibaba/open-code-review@5cf97d0d15 (2026-09-02).
Data as JSON: /api/errors/84be42b5e271ac8a.
Report an issue: GitHub.