{"record":{"id":"2a7191d4350e1d8e","repo":"github/copilot-sdk","slug":"setmodeloptions-autotier-and-setmodeloptions-reset","errorCode":null,"errorMessage":"SetModelOptions.AutoTier and SetModelOptions.ResetAutoTier are mutually exclusive.","messagePattern":"SetModelOptions\\.AutoTier and SetModelOptions\\.ResetAutoTier are mutually exclusive\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Session.cs","lineNumber":2037,"sourceCode":"            },\n            cancellationToken);\n    }\n\n    /// <summary>\n    /// Changes the model for this session.\n    /// The new model takes effect for the next message. Conversation history is preserved.\n    /// </summary>\n    /// <param name=\"model\">Model ID to switch to (e.g., \"gpt-5.4\").</param>\n    /// <param name=\"options\">Settings for the new model.</param>\n    /// <param name=\"cancellationToken\">Optional cancellation token.</param>\n    public async Task SetModelAsync(string model, SetModelOptions options, CancellationToken cancellationToken = default)\n    {\n        ArgumentNullException.ThrowIfNull(model);\n        ThrowIfDisposed();\n\n        if (options.AutoTier is not null && options.ResetAutoTier)\n        {\n            throw new ArgumentException(\n                $\"{nameof(SetModelOptions.AutoTier)} and {nameof(SetModelOptions.ResetAutoTier)} are mutually exclusive.\",\n                nameof(options));\n        }\n\n        if (options.ResetAutoTier)\n        {\n            var request = new ModelSwitchToRequest\n            {\n                SessionId = SessionId,\n                ModelId = model,\n                ReasoningEffort = options.ReasoningEffort,\n                ReasoningSummary = options.ReasoningSummary,\n                ModelCapabilities = options.ModelCapabilities,\n                ContextTier = options.ContextTier,\n            };\n            await CopilotClient.InvokeRpcAsync(\n                Rpc,\n                \"session.model.switchTo\",","sourceCodeStart":2019,"sourceCodeEnd":2055,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/dotnet/src/Session.cs#L2019-L2055","documentation":"SetModelAsync validates SetModelOptions before applying: AutoTier (set a specific auto-tier) and ResetAutoTier (clear auto-tier) are contradictory operations, so supplying both non-null AutoTier and ResetAutoTier=true is rejected with ArgumentException, with nameof(options) as paramName.","triggerScenarios":"Calling session.SetModelAsync(model, new SetModelOptions { AutoTier = \"premium\", ResetAutoTier = true }) — any call where both properties are set.","commonSituations":"Merging user-supplied settings objects where ResetAutoTier defaults true and AutoTier was also filled from config; copy-paste of option objects across code paths; UI forms that submit both fields.","solutions":["Set only one: either AutoTier = \"<tier>\" or ResetAutoTier = true, never both.","If options come from merged config, null out ResetAutoTier whenever AutoTier is provided (or vice versa).","Catch ArgumentException (paramName == \"options\") to report a clear validation message to the user."],"exampleFix":"// before\nawait session.SetModelAsync(\"gpt-5\", new SetModelOptions { AutoTier = \"premium\", ResetAutoTier = true });\n\n// after\nvar opts = new SetModelOptions { AutoTier = \"premium\", ResetAutoTier = opts?.AutoTier is null };\nawait session.SetModelAsync(\"gpt-5\", opts.AutoTier is null ? new SetModelOptions { ResetAutoTier = true } : new SetModelOptions { AutoTier = opts.AutoTier });","handlingStrategy":"validation","validationCode":"if (options.AutoTier is not null && options.ResetAutoTier)\n    throw new ArgumentException(\"Set only one of AutoTier or ResetAutoTier\", nameof(options));","typeGuard":"static bool OptionsConsistent(SetModelOptions o) => o.AutoTier is null || !o.ResetAutoTier;","tryCatchPattern":"try { await session.SetModelAsync(model, options); }\ncatch (ArgumentException ex) when (ex.ParamName == \"options\" && ex.Message.Contains(\"mutually exclusive\"))\n{ NotifyUser(\"Choose either an auto tier or a reset, not both.\"); }","preventionTips":["Never merge AutoTier and ResetAutoTier from independent config sources","Null out ResetAutoTier when AutoTier is set after merging options","Centralize option construction in one factory to keep invariants"],"tags":["argument-validation","conflicting-options","model-selection","dotnet"],"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"}