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

  1. Set only one of AutoTier or ResetAutoTier in SetModelOptions.
  2. If reset was intended, pass AutoTier = nil.
  3. 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

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


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)