github/copilot-sdk · error

failed to set model

Error message

failed to set model: %w

What it means

Session's model-switch path (SetModel) builds switch parameters (model, optional provider, auto-tier defaults) and calls s.RPC.Model.SwitchTo. This error wraps any failure of that RPC — unknown model/provider identifier, invalid auto-tier combination, or transport failure.

Solutions

  1. Verify the model ID/provider string against the runtime's model list
  2. Check that the AutoTier value is valid for the chosen provider
  3. Inspect the wrapped error for the runtime's specific rejection reason
  4. Upgrade SDK/runtime together if the model was added in a newer release

Example fix

// before
err := session.SetModel(ctx, "gpt-5-turbo", "")
// after
if err := session.SetModel(ctx, "gpt-5-turbo", ""); err != nil {
    log.Printf("set model failed: %v — check model/provider IDs", err)
}
Defensive patterns

Strategy: validation

Validate before calling

var validModels = map[string]bool{"claude-sonnet-4": true /* ...from runtime list */}
if !validModels[modelID] {
    return fmt.Errorf("unknown model %q", modelID)
}

Try / catch

if err := session.SetModel(ctx, model, provider); err != nil {
    log.Printf("set model failed: %v", err)
    return fmt.Errorf("model %q/provider %q rejected: %w", model, provider, err)
}

Prevention

When it happens

Trigger: Calling SetModel (or the session model API) with a model/provider identifier the runtime rejects, an unsupported AutoTier value for that provider, or when the RPC transport fails.

Common situations: Typo'd model ID; referencing a model removed in a newer runtime; passing a provider that doesn't serve the requested model; setting AutoTier on a provider without tier support.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/2971202e7fb06217. Report an issue: GitHub.

Appendix: source

Thrown at go/session.go:2006

		params.ReasoningSummary = opts.ReasoningSummary
		params.ContextTier = opts.ContextTier
		params.ModelCapabilities = opts.ModelCapabilities

		// The generated field is a double pointer so the three cases stay
		// distinct on the wire: a nil outer pointer omits the field and leaves
		// any staged preference alone, while a non-nil outer pointer sends the
		// inner value, including an explicit null.
		switch {
		case opts.AutoTier != nil:
			params.AutoTier = &opts.AutoTier
		case opts.ResetAutoTier:
			var providerDefault *AutoTier
			params.AutoTier = &providerDefault
		}
	}
	_, err := s.RPC.Model.SwitchTo(ctx, params)
	if err != nil {
		return fmt.Errorf("failed to set model: %w", err)
	}

	return nil
}

// SetAutoTier changes the Auto routing preference without changing the selected model.
//
// The runtime does not apply the preference immediately. It records the request and
// commits it only when a later user turn using the "auto" model successfully obtains a
// usable model from the provider. A [rpc.ModelSwitchAutoTierStatusPending] status
// therefore confirms that the request was accepted, not that it took effect.
//
// Watch for the outcome through the session.model_change event on success, or the
// ephemeral session.auto_tier_switch_failed event on failure. You can also read the
// current committed and in-flight state at any time with session.RPC.Model.GetCurrent.
//
// Only the most recent request survives: issuing a new request replaces any earlier one
// that has not yet been claimed by a turn.

View on GitHub (pinned to cd8cf15dc3)