{"record":{"id":"9dfd939509fe129a","repo":"git-ecosystem/git-credential-manager","slug":"provided-uri-organizationuri-is-not-a-valid-az","errorCode":null,"errorMessage":"Provided URI '{organizationUri}' is not a valid Azure DevOps hostname","messagePattern":"Provided URI '(.+?)' is not a valid Azure DevOps hostname","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.AzureRepos/AzureDevOpsRestApi.cs","lineNumber":113,"sourceCode":"                    AzureDevOpsConstants.EnvironmentVariables.DevAadAuthorityBaseUri,\n                    Constants.GitConfiguration.Credential.SectionName, AzureDevOpsConstants.GitConfiguration.Credential.DevAadAuthorityBaseUri,\n                    out string redirectUriStr) &&\n                Uri.TryCreate(redirectUriStr, UriKind.Absolute, out Uri authorityBase))\n            {\n                return authorityBase;\n            }\n\n            return new Uri(AzureDevOpsConstants.AadAuthorityBaseUrl);\n        }\n\n        public async Task<string> CreatePersonalAccessTokenAsync(Uri organizationUri, string accessToken, IEnumerable<string> scopes)\n        {\n            const string sessionTokenUrl = \"_apis/token/sessiontokens?api-version=1.0&tokentype=compact\";\n\n            EnsureArgument.AbsoluteUri(organizationUri, nameof(organizationUri));\n            if (!UriHelpers.IsAzureDevOpsHost(organizationUri.Host))\n            {\n                throw new ArgumentException($\"Provided URI '{organizationUri}' is not a valid Azure DevOps hostname\", nameof(organizationUri));\n            }\n            EnsureArgument.NotNull(accessToken, nameof(accessToken));\n\n            _context.Trace.WriteLine(\"Getting Azure DevOps Identity Service endpoint...\");\n            Uri identityServiceUri = await GetIdentityServiceUriAsync(organizationUri, accessToken);\n            _context.Trace.WriteLine($\"Identity Service endpoint is '{identityServiceUri}'.\");\n\n            Uri requestUri = new Uri(identityServiceUri, sessionTokenUrl);\n\n            _context.Trace.WriteLine($\"HTTP: POST {requestUri}\");\n            using (StringContent content = CreateAccessTokenRequestJson(organizationUri, scopes))\n            using (HttpRequestMessage request = CreateRequestMessage(HttpMethod.Post, requestUri, content, accessToken))\n            using (HttpResponseMessage response = await HttpClient.SendAsync(request))\n            {\n                _context.Trace.WriteLine($\"HTTP: Response {(int)response.StatusCode} [{response.StatusCode}]\");\n\n                string responseText = await response.Content.ReadAsStringAsync();\n","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/git-ecosystem/git-credential-manager/blob/e8ce762cd04b4100ae637b5fbf39ef9d0a96561e/src/Microsoft.AzureRepos/AzureDevOpsRestApi.cs#L95-L131","documentation":"CreatePersonalAccessTokenAsync validates that the organization URI host is a recognized Azure DevOps host (dev.azure.com or *.visualstudio.com per UriHelpers.IsAzureDevOpsHost) before calling the API. A non-DevOps URL raises ArgumentException naming the offending URI.","triggerScenarios":"Calling AzureDevOpsRestApi.CreatePersonalAccessTokenAsync with a URI whose host is not an Azure DevOps hostname - e.g. an on-premises Azure DevOps Server URL, a GitHub/GitLab URL, or a mistyped host.","commonSituations":"Using GCM's Azure DevOps PAT creation against Azure DevOps Server (on-prem) which has a custom hostname; passing a full repository URL instead of the organization URL; DNS typos.","solutions":["Pass the hosted Azure DevOps organization URL, e.g. https://dev.azure.com/your-org/.","For on-premises Azure DevOps Server, do not use this hosted-host validation path - configure the provider for Azure DevOps Server explicitly.","Verify the host with UriHelpers.IsAzureDevOpsHost logic before calling; fix typos in the hostname."],"exampleFix":"// before\nvar uri = new Uri(\"https://mycompany.visualstudio.com.default/MyProj\");\n// after\nvar uri = new Uri(\"https://dev.azure.com/myorganization\");","handlingStrategy":"validation","validationCode":"// Validate the org URI host before calling CreatePersonalAccessTokenAsync\nvar uri = new Uri(organizationUri);\nbool isAdoHost = uri.Host == \"dev.azure.com\" || uri.Host.EndsWith(\".visualstudio.com\");\nif (!isAdoHost) throw new ArgumentException($\"{organizationUri} is not a hosted Azure DevOps organization URL\");","typeGuard":null,"tryCatchPattern":"try {\n  var pat = await restApi.CreatePersonalAccessTokenAsync(orgUri, accessToken);\n} catch (ArgumentException ex) when (ex.Message.Contains(\"not a valid Azure DevOps hostname\")) {\n  // normalize to https://dev.azure.com/{org} and retry\n}","preventionTips":["Always construct the organization URL as https://dev.azure.com/{org}","Do not pass repository or project URLs where an organization URI is expected","Use a separate auth path for Azure DevOps Server (on-premises) instances"],"tags":["azure-devops","uri-validation","argument"],"backgroundTag":"invalid-url-format","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"}