github/copilot-sdk · error
failed to set model: AutoTier and ResetAutoTier are…
Error message
failed to set model: AutoTier and ResetAutoTier are mutually exclusive
What it means
Session.SetModel rejects options where both AutoTier and ResetAutoTier are set, because they are contradictory: one asks the runtime to auto-select a tier, the other asks it to clear auto-tiering. The SDK validates this locally before issuing any RPC.
Solutions
- Set only one of AutoTier or ResetAutoTier in SetModelOptions.
- If reset was intended, pass AutoTier = nil.
- Validate options before constructing them to catch conflicts early.
Example fix
// before
opts := &SetModelOptions{AutoTier: &trueVal, ResetAutoTier: true}
// after
opts := &SetModelOptions{AutoTier: &trueVal} // drop ResetAutoTier Defensive patterns
Strategy: validation
Validate before calling
if opts != nil && opts.AutoTier != nil && opts.ResetAutoTier { return errors.New("AutoTier and ResetAutoTier are mutually exclusive") } Try / catch
if err := s.SetModel(ctx, model, opts); err != nil { if strings.Contains(err.Error(), "mutually exclusive") { /* fix opts */ } } Prevention
- Construct SetModelOptions in one place
- Never merge AutoTier and ResetAutoTier flags
- Add unit test covering the conflict
When it happens
Trigger: Calling Session.SetModel with a *SetModelOptions whose AutoTier pointer is non-nil AND whose ResetAutoTier bool is true.
Common situations: Merging user config where auto-tier and reset-auto-tier flags both got enabled; copying options from two different code paths into one struct.
Related errors
- BuiltinPluginDirectories must contain only absolute paths…
- SessionFS.SessionStatePath is required
- SessionFS.Conventions must be either 'posix' or 'windows'
- Client is in Mode=ModeEmpty but the session config did not…
- invalid AskUserVariant
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/6f1f3daab067e13b.
Report an issue: GitHub.
Appendix: source
Thrown at go/session.go:1985
ResetAutoTier bool
}
// SetModel changes the model for this session.
// The new model takes effect for the next message. Conversation history is preserved.
//
// Example:
//
// if err := session.SetModel(context.Background(), "gpt-5.4", nil); err != nil {
// log.Printf("Failed to set model: %v", err)
// }
// if err := session.SetModel(context.Background(), "claude-sonnet-4.6", &SetModelOptions{ReasoningEffort: new("high")}); err != nil {
// log.Printf("Failed to set model: %v", err)
// }
func (s *Session) SetModel(ctx context.Context, model string, opts *SetModelOptions) error {
params := &rpc.ModelSwitchToRequest{ModelID: model}
if opts != nil {
if opts.AutoTier != nil && opts.ResetAutoTier {
return errors.New("failed to set model: AutoTier and ResetAutoTier are mutually exclusive")
}
params.ReasoningEffort = opts.ReasoningEffort
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
}
}View on GitHub (pinned to cd8cf15dc3)