{"record":{"id":"b195ec2d49835c16","repo":"git-ecosystem/git-credential-manager","slug":"missing-pat-in-response-b195ec","errorCode":null,"errorMessage":"Missing 'pat' in response","messagePattern":"Missing 'pat' in response","errorType":"exception","errorClass":"Trace2Exception","httpStatus":null,"severity":"error","filePath":"src/GitLab/GitLabAuthentication.cs","lineNumber":227,"sourceCode":"            promptArgs.AppendFormat(\" --url {0}\", QuoteCmdArg(targetUri.ToString()));\n\n            if ((modes & AuthenticationModes.Basic) != 0) promptArgs.Append(\" --basic\");\n            if ((modes & AuthenticationModes.Browser) != 0) promptArgs.Append(\" --browser\");\n            if ((modes & AuthenticationModes.Pat) != 0) promptArgs.Append(\" --pat\");\n\n            IDictionary<string, string> resultDict = await InvokeHelperAsync(helperCommand, promptArgs.ToString());\n\n            if (!resultDict.TryGetValue(\"mode\", out string responseMode))\n            {\n                throw new Trace2Exception(Context.Trace2, \"Missing 'mode' in response\");\n            }\n\n            switch (responseMode.ToLowerInvariant())\n            {\n                case \"pat\":\n                    if (!resultDict.TryGetValue(\"pat\", out string pat))\n                    {\n                        throw new Trace2Exception(Context.Trace2, \"Missing 'pat' in response\");\n                    }\n\n                    if (!resultDict.TryGetValue(\"username\", out string patUserName))\n                    {\n                        // Username is optional for PATs\n                    }\n\n                    return new AuthenticationPromptResult(\n                        AuthenticationModes.Pat, new GitCredential(patUserName, pat));\n\n                case \"browser\":\n                    return new AuthenticationPromptResult(AuthenticationModes.Browser);\n\n                case \"basic\":\n                    if (!resultDict.TryGetValue(\"username\", out userName))\n                    {\n                        throw new Trace2Exception(Context.Trace2, \"Missing 'username' in response\");\n                    }","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/git-ecosystem/git-credential-manager/blob/e8ce762cd04b4100ae637b5fbf39ef9d0a96561e/src/GitLab/GitLabAuthentication.cs#L209-L245","documentation":"Thrown in GetAuthenticationViaHelperAsync when the GitLab helper response declares `mode=pat` but the result dictionary contains no 'pat' key. A PAT-mode response is required to carry the personal access token value, so the missing field is a protocol violation.","triggerScenarios":"Helper returns mode=pat but omits the pat= line - e.g. a script that failed to read the token but still printed the mode, or a partially-implemented custom helper.","commonSituations":"Custom helper scripts whose token retrieval failed silently; helpers reading tokens from files/env vars that are empty or unset; truncated helper output due to pipe errors.","solutions":["Fix the helper to only emit `mode=pat` together with a non-empty `pat=` line.","Verify the token source the helper reads (env var, file, CLI) is actually populated before invoking git.","Switch to GCM's built-in GitLab authentication (remove the custom helper override) if the custom helper cannot be maintained."],"exampleFix":"// before\nif [ -z \"$TOKEN\" ]; then echo \"mode=pat\"; exit 0; fi\necho \"mode=pat\"\necho \"pat=$TOKEN\"\n// after\necho \"mode=pat\"\necho \"pat=$TOKEN\"","handlingStrategy":"validation","validationCode":"// Ensure token is present before emitting pat mode\nif [ -z \"$GITLAB_PAT\" ]; then echo \"Error: GITLAB_PAT not set\" >&2; exit 1; fi\necho \"mode=pat\"\necho \"pat=$GITLAB_PAT\"","typeGuard":null,"tryCatchPattern":"try {\n  var result = await auth.GetAuthenticationAsync(...);\n} catch (Trace2Exception ex) when (ex.Message.Contains(\"Missing 'pat' in response\")) {\n  // helper is broken; prompt for PAT manually\n  var pat = Console.ReadLine();\n}","preventionTips":["Verify token env vars/files exist before invoking git with a custom helper","Only emit mode=pat when the token is non-empty","Keep helper output minimal and structured"],"tags":["gitlab","credential-helper","pat"],"backgroundTag":"missing-credentials","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"}