{"record":{"id":"4a25a63f85db0375","repo":"github/github-mcp-server","slug":"authorization-prompt-has-expired","errorCode":null,"errorMessage":"authorization prompt has expired","messagePattern":"authorization prompt has expired","errorType":"exception","errorClass":"ErrStaleAuthorizationFlow","httpStatus":null,"severity":"error","filePath":"internal/oauth/manager.go","lineNumber":26,"sourceCode":"\t\"net/http\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n\n\t\"golang.org/x/oauth2\"\n)\n\n// DefaultAuthTimeout bounds how long a single authorization attempt waits for\n// the user to complete the browser or device flow.\nconst DefaultAuthTimeout = 5 * time.Minute\n\n// tokenRefreshTimeout bounds each background refresh of an expiring token so a\n// stalled GitHub token endpoint cannot block a tool call indefinitely.\nconst tokenRefreshTimeout = 30 * time.Second\n\n// ErrStaleAuthorizationFlow indicates that a prompt response belongs to an\n// authorization flow that is no longer current.\nvar ErrStaleAuthorizationFlow = errors.New(\"authorization prompt has expired\")\n\n// flowStatus tracks the manager's single-flight authorization state.\ntype flowStatus int\n\nconst (\n\tstatusIdle         flowStatus = iota // no flow running\n\tstatusStarting                       // a flow is being prepared (brief)\n\tstatusInProgress                     // a flow is running on a secure channel; callers may join\n\tstatusAwaitingUser                   // a flow is running but the user must act out-of-band\n)\n\n// Outcome reports the result of an authorization attempt that did not\n// immediately yield a token.\ntype Outcome struct {\n\t// UserAction, when non-nil, must be surfaced to the user. The authorization\n\t// flow continues in the background; the user should retry once they have\n\t// completed it.\n\tUserAction *UserAction","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/github/github-mcp-server/blob/0ea1f775a7c73eff1bd2e25904d01136756bbfe2/internal/oauth/manager.go#L8-L44","documentation":"First guard of validateBlamePath, run by get_file_blame before any network call: strings.TrimSpace(path) == \"\" is rejected. The GraphQL blame query needs a concrete file path; an empty or all-whitespace path would either fail at GitHub or match nothing, so the server refuses it locally with 'path must not be empty'.","triggerScenarios":"Omitting the path argument so it defaults to \"\"; passing a whitespace-only string (spaces/tabs/newlines); templating bugs that interpolate an unset variable into path.","commonSituations":"LLM tool calls that drop a required parameter; CI scripts iterating a file list where one entry is blank; config-driven blame jobs with an empty template slot.","solutions":["Pass a real repository-relative file path such as \"src/main.go\"","If the path comes from a variable, default it and skip the call when blank rather than sending whitespace","Trim inputs before invoking the tool to catch the mistake client-side"],"exampleFix":"// before\n{\"owner\":\"octocat\",\"repo\":\"Hello-World\",\"path\":\"   \"}\n\n// after\n{\"owner\":\"octocat\",\"repo\":\"Hello-World\",\"path\":\"README.md\"}","handlingStrategy":"validation","validationCode":"func validBlamePathPresence(p string) bool {\n\treturn strings.TrimSpace(p) != \"\"\n}","typeGuard":"func isBlamePathError(err error) bool {\n\treturn err != nil && strings.HasPrefix(err.Error(), \"path must\")\n}","tryCatchPattern":"if strings.TrimSpace(path) == \"\" {\n\t// skip or fetch a default file instead of calling with a blank path\n\treturn nil, fmt.Errorf(\"no file path provided\")\n}\nres, _, err := callGetFileBlame(ctx, buildArgs(owner, repo, path))\nif isBlamePathError(err) {\n\treturn nil, fmt.Errorf(\"fix the path argument: %w\", err)\n}","preventionTips":["Make path a required field in calling code, not an optional default","Skip blank entries when iterating file lists","Trim inputs before invoking the tool","Fail fast client-side - the server only re-rejects what you could have checked"],"tags":["go","validation","user-input","blame"],"backgroundTag":null,"analyzedSha":"0ea1f775a7c73eff1bd2e25904d01136756bbfe2","analyzedAt":"2026-08-15T18:10:19.804Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}