{"record":{"id":"6f1f3daab067e13b","repo":"github/copilot-sdk","slug":"failed-to-set-model-autotier-and-resetautotier-ar","errorCode":null,"errorMessage":"failed to set model: AutoTier and ResetAutoTier are mutually exclusive","messagePattern":"failed to set model: AutoTier and ResetAutoTier are mutually exclusive","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/session.go","lineNumber":1985,"sourceCode":"\tResetAutoTier bool\n}\n\n// SetModel changes the model for this session.\n// The new model takes effect for the next message. Conversation history is preserved.\n//\n// Example:\n//\n//\tif err := session.SetModel(context.Background(), \"gpt-5.4\", nil); err != nil {\n//\t    log.Printf(\"Failed to set model: %v\", err)\n//\t}\n//\tif err := session.SetModel(context.Background(), \"claude-sonnet-4.6\", &SetModelOptions{ReasoningEffort: new(\"high\")}); err != nil {\n//\t    log.Printf(\"Failed to set model: %v\", err)\n//\t}\nfunc (s *Session) SetModel(ctx context.Context, model string, opts *SetModelOptions) error {\n\tparams := &rpc.ModelSwitchToRequest{ModelID: model}\n\tif opts != nil {\n\t\tif opts.AutoTier != nil && opts.ResetAutoTier {\n\t\t\treturn errors.New(\"failed to set model: AutoTier and ResetAutoTier are mutually exclusive\")\n\t\t}\n\t\tparams.ReasoningEffort = opts.ReasoningEffort\n\t\tparams.ReasoningSummary = opts.ReasoningSummary\n\t\tparams.ContextTier = opts.ContextTier\n\t\tparams.ModelCapabilities = opts.ModelCapabilities\n\n\t\t// The generated field is a double pointer so the three cases stay\n\t\t// distinct on the wire: a nil outer pointer omits the field and leaves\n\t\t// any staged preference alone, while a non-nil outer pointer sends the\n\t\t// inner value, including an explicit null.\n\t\tswitch {\n\t\tcase opts.AutoTier != nil:\n\t\t\tparams.AutoTier = &opts.AutoTier\n\t\tcase opts.ResetAutoTier:\n\t\t\tvar providerDefault *AutoTier\n\t\t\tparams.AutoTier = &providerDefault\n\t\t}\n\t}","sourceCodeStart":1967,"sourceCodeEnd":2003,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/go/session.go#L1967-L2003","documentation":"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.","triggerScenarios":"Calling Session.SetModel with a *SetModelOptions whose AutoTier pointer is non-nil AND whose ResetAutoTier bool is true.","commonSituations":"Merging user config where auto-tier and reset-auto-tier flags both got enabled; copying options from two different code paths into one struct.","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."],"exampleFix":"// before\nopts := &SetModelOptions{AutoTier: &trueVal, ResetAutoTier: true}\n// after\nopts := &SetModelOptions{AutoTier: &trueVal} // drop ResetAutoTier","handlingStrategy":"validation","validationCode":"if opts != nil && opts.AutoTier != nil && opts.ResetAutoTier { return errors.New(\"AutoTier and ResetAutoTier are mutually exclusive\") }","typeGuard":null,"tryCatchPattern":"if err := s.SetModel(ctx, model, opts); err != nil { if strings.Contains(err.Error(), \"mutually exclusive\") { /* fix opts */ } }","preventionTips":["Construct SetModelOptions in one place","Never merge AutoTier and ResetAutoTier flags","Add unit test covering the conflict"],"tags":["go","validation","config"],"backgroundTag":"mutually-exclusive-options","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}