{"record":{"id":"2ac7a013947b0d91","repo":"git-ecosystem/git-credential-manager","slug":"no-device-authorization-endpoint-has-been-configur","errorCode":null,"errorMessage":"No device authorization endpoint has been configured for this client.","messagePattern":"No device authorization endpoint has been configured for this client\\.","errorType":"exception","errorClass":"Trace2InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Core/Authentication/OAuth/OAuth2Client.cs","lineNumber":207,"sourceCode":"\r\n            // We expect to have the auth code in the response otherwise terminate the flow (we failed authentication for some reason)\r\n            if (!responseParams.TryGetValue(OAuth2Constants.AuthorizationGrantResponse.AuthorizationCodeParameter, out string authCode))\r\n            {\r\n                throw new Trace2OAuth2Exception(_trace2,\r\n                    $\"Missing '{OAuth2Constants.AuthorizationGrantResponse.AuthorizationCodeParameter}' in response.\");\r\n            }\r\n\r\n            return new OAuth2AuthorizationCodeResult(authCode, redirectUri, codeVerifier);\r\n        }\r\n\r\n        public async Task<OAuth2DeviceCodeResult> GetDeviceCodeAsync(IEnumerable<string> scopes, CancellationToken ct)\r\n        {\r\n            var label = \"get device code\";\r\n            using IDisposable region = _trace2.CreateRegion(OAuth2Constants.Trace2Category, label);\r\n\r\n            if (_endpoints.DeviceAuthorizationEndpoint is null)\r\n            {\r\n                throw new Trace2InvalidOperationException(_trace2,\r\n                    \"No device authorization endpoint has been configured for this client.\");\r\n            }\r\n\r\n            string scopesStr = string.Join(\" \", scopes);\r\n\r\n            var formData = new Dictionary<string, string>\r\n            {\r\n                [OAuth2Constants.ClientIdParameter] = _clientId\r\n            };\r\n\r\n            if (!string.IsNullOrWhiteSpace(scopesStr))\r\n            {\r\n                formData[OAuth2Constants.ScopeParameter] = scopesStr;\r\n            }\r\n\r\n            using (HttpContent requestContent = new FormUrlEncodedContent(formData))\r\n            using (HttpRequestMessage request = CreateRequestMessage(HttpMethod.Post, _endpoints.DeviceAuthorizationEndpoint, requestContent))\r\n            using (HttpResponseMessage response = await _httpClient.SendAsync(request, ct))\r","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/git-ecosystem/git-credential-manager/blob/e8ce762cd04b4100ae637b5fbf39ef9d0a96561e/src/Core/Authentication/OAuth/OAuth2Client.cs#L189-L225","documentation":"GetDeviceCodeAsync requires a device authorization endpoint to be configured on the client's endpoint collection (_endpoints.DeviceAuthorizationEndpoint). When the OAuth2 client was created without one, the device code flow cannot even be started, so the library throws Trace2InvalidOperationException before making any network call.","triggerScenarios":"Calling GetDeviceCodeAsync on an OAuth2Client whose endpoints (from the OpenID Connect discovery / authority metadata) lack a device_authorization_endpoint — either the endpoints dictionary was built manually without it or the authority's discovery document does not advertise device code support.","commonSituations":"Pointing the client at a token endpoint or authority whose metadata does not include device_authorization_endpoint (e.g. some ADFS or on-prem STS configurations); constructing OAuth2Endpoints manually with only token/authorization endpoints; an older authority that predates device code flow support.","solutions":["Configure a valid device authorization endpoint on the client's endpoints before calling GetDeviceCodeAsync (typically from the authority's OIDC discovery document).","Use a modern Azure AD/Entra authority (e.g. https://login.microsoftonline.com/{tenant}) whose discovery document advertises device_authorization_endpoint.","If endpoints are built manually, add the device authorization endpoint (for Entra: https://login.microsoftonline.com/{tenant}/oauth2/v2.0/devicecode).","Fall back to a different interaction mode (webview-based) if the authority does not support device code flow."],"exampleFix":"// before\nvar endpoints = new OAuth2Endpoints(authorizationEndpoint, tokenEndpoint); // no device endpoint\nawait client.GetDeviceCodeAsync(endpoints, scopes, ct); // throws\n// after\nvar endpoints = new OAuth2Endpoints(authorizationEndpoint, tokenEndpoint,\n    deviceAuthorizationEndpoint: \"https://login.microsoftonline.com/{tenant}/oauth2/v2.0/devicecode\");\nawait client.GetDeviceCodeAsync(endpoints, scopes, ct);","handlingStrategy":"validation","validationCode":"if (endpoints.DeviceAuthorizationEndpoint is null)\n    throw new InvalidOperationException(\"Device authorization endpoint not configured; cannot use device code flow.\");","typeGuard":null,"tryCatchPattern":"try\n{\n    deviceResult = await client.GetDeviceCodeAsync(endpoints, scopes, ct);\n}\ncatch (Trace2InvalidOperationException ex) when (ex.Message.Contains(\"device authorization endpoint\"))\n{\n    // fall back to a webview-based interaction mode or reconfigure endpoints\n    return AuthFailure.NoDeviceEndpoint;\n}","preventionTips":["Resolve endpoints from the authority's OIDC discovery document rather than building them by hand.","Verify the discovery metadata contains device_authorization_endpoint before choosing device code flow.","Use a modern Entra ID authority that supports device code flow.","Configure a fallback interaction mode when the authority lacks device code support."],"tags":["oauth2","device-code-flow","configuration","missing-endpoint"],"backgroundTag":"missing-required-config","analyzedSha":"e8ce762cd04b4100ae637b5fbf39ef9d0a96561e","analyzedAt":"2026-09-11T17:15:08.753Z","contentChangedAt":"2026-09-11T17:15:08.753Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}