{"record":{"id":"5c330c60b46b2af0","repo":"git-ecosystem/git-credential-manager","slug":"missing-username-in-response-5c330c","errorCode":null,"errorMessage":"Missing 'username' in response","messagePattern":"Missing 'username' in response","errorType":"exception","errorClass":"Trace2Exception","httpStatus":null,"severity":"error","filePath":"src/GitHub/GitHubAuthentication.cs","lineNumber":332,"sourceCode":"                case \"pat\":\n                    if (!resultDict.TryGetValue(\"pat\", out string pat))\n                    {\n                        throw new Trace2Exception(Context.Trace2, \"Missing 'pat' in response\");\n                    }\n\n                    return new AuthenticationPromptResult(\n                        AuthenticationModes.Pat, new GitCredential(userName, pat));\n\n                case \"browser\":\n                    return new AuthenticationPromptResult(AuthenticationModes.Browser);\n\n                case \"device\":\n                    return new AuthenticationPromptResult(AuthenticationModes.Device);\n\n                case \"basic\":\n                    if (!resultDict.TryGetValue(\"username\", out userName))\n                    {\n                        throw new Trace2Exception(Context.Trace2, \"Missing 'username' in response\");\n                    }\n\n                    if (!resultDict.TryGetValue(\"password\", out string password))\n                    {\n                        throw new Trace2Exception(Context.Trace2, \"Missing 'password' in response\");\n                    }\n\n                    return new AuthenticationPromptResult(\n                        AuthenticationModes.Basic, new GitCredential(userName, password));\n\n                default:\n                    throw new Trace2Exception(Context.Trace2,\n                        $\"Unknown mode value in response '{responseMode}'\");\n            }\n        }\n\n        public async Task<string> GetTwoFactorCodeAsync(Uri targetUri, bool isSms)\n        {","sourceCodeStart":314,"sourceCodeEnd":350,"githubUrl":"https://github.com/git-ecosystem/git-credential-manager/blob/e8ce762cd04b4100ae637b5fbf39ef9d0a96561e/src/GitHub/GitHubAuthentication.cs#L314-L350","documentation":"For response mode 'basic', the helper must return both 'username' and 'password'. This exception is thrown when mode=basic arrives without a 'username' key, meaning the helper's basic-auth prompt produced no username. The credential pair is incomplete, so the method cannot return a valid AuthenticationPromptResult.","triggerScenarios":"Helper returns mode=basic but the dictionary lacks 'username': the basic auth dialog was dismissed after mode selection, a custom helper omitted the key, or output parsing dropped it.","commonSituations":"Users pressing Cancel on the username field of the basic auth dialog with a nonconforming helper; custom or older helper builds that don't emit all basic-mode keys; locale/encoding issues corrupting key output.","solutions":["Upgrade GCM/helper to a consistent version and retry authentication","Complete the basic auth dialog fully (enter username and password) instead of dismissing it","Use an alternative auth mode (browser, device, or PAT) that avoids the basic prompt","If implementing a custom helper, always emit username and password together with mode=basic"],"exampleFix":"// before\noutput[\"mode\"] = \"basic\"; // username/password possibly unset\n// after\nif (!string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password))\n{\n    output[\"mode\"] = \"basic\";\n    output[\"username\"] = username;\n    output[\"password\"] = password;\n}","handlingStrategy":"try-catch","validationCode":"// Prefer modes that do not require the basic username prompt when helper contract is uncertain\nvar supported = new[] { \"browser\", \"device\", \"pat\" };\n// configure GCM to use a non-basic mode:\n// git config --global credential.github.com.gitHubAuthModes browser,pat,device","typeGuard":null,"tryCatchPattern":"try\n{\n    var result = await auth.GetAuthenticationAsync(uri, userName);\n}\ncatch (Trace2Exception ex) when (ex.Message.StartsWith(\"Missing 'username'\"))\n{\n    trace.WriteLine(\"Basic auth helper response missing username; falling back to another mode.\");\n    throw;\n}","preventionTips":["Complete both username and password fields in the basic auth dialog","Configure preferred auth modes (browser/pat) to avoid the basic prompt entirely","Keep helper and core versions matched","Validate custom helper output emits username+password together with mode=basic"],"tags":["github","authentication","basic-auth","helper-contract"],"backgroundTag":"response-missing-required-field","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"}