{"record":{"id":"699255bc3efd2a07","repo":"mislav/hub","slug":"s","errorCode":null,"errorMessage":"%s","messagePattern":"%s","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"github/client.go","lineNumber":1266,"sourceCode":"\t} else {\n\t\terrorMessage = e.Message\n\t\tif action == \"getting current user\" && e.Message == \"Resource not accessible by integration\" {\n\t\t\terrorMessage = errorMessage + \"\\nYou must specify GITHUB_USER via environment variable.\"\n\t\t}\n\t}\n\tif errorMessage != \"\" {\n\t\terrStr = fmt.Sprintf(\"%s\\n%s\", errStr, errorMessage)\n\t}\n\n\tif ssoErr := ValidateGitHubSSO(e.Response); ssoErr != nil {\n\t\treturn fmt.Errorf(\"%s\\n%s\", errStr, ssoErr)\n\t}\n\n\tif scopeErr := ValidateSufficientOAuthScopes(e.Response); scopeErr != nil {\n\t\treturn fmt.Errorf(\"%s\\n%s\", errStr, scopeErr)\n\t}\n\n\treturn errors.New(errStr)\n}\n\n// ValidateGitHubSSO checks for the challenge via `X-Github-Sso` header\nfunc ValidateGitHubSSO(res *http.Response) error {\n\tif res.StatusCode != 403 {\n\t\treturn nil\n\t}\n\n\tsso := res.Header.Get(\"X-Github-Sso\")\n\tif !strings.HasPrefix(sso, \"required; url=\") {\n\t\treturn nil\n\t}\n\n\turl := sso[strings.IndexByte(sso, '=')+1:]\n\treturn fmt.Errorf(\"You must authorize your token to access this organization:\\n%s\", url)\n}\n\n// ValidateSufficientOAuthScopes warns about insufficient OAuth scopes","sourceCodeStart":1248,"sourceCodeEnd":1284,"githubUrl":"https://github.com/mislav/hub/blob/5c547ed804368763064e51f3990851e267e88edd/github/client.go#L1248-L1284","documentation":"When an HTTP API request fails (e.g. a 4xx/5xx response), hub builds an errStr from the response and then calls ValidateSufficientOAuthScopes on the response. If the response indicates the token lacks required OAuth scopes (via the X-Accepted-OAuth-Scopes / X-OAuth-Scopes headers), the scope-validation error is appended to the original error message with fmt.Errorf(\"%s\\n%s\"). This means the thrown error is a compound: the API failure plus a hint that your token's scopes are insufficient.","triggerScenarios":"Any failing GitHub API call made with a token whose scopes don't include what the endpoint requires (e.g. a token without 'repo' scope accessing a private repository, or missing 'gist'/'read:org' scopes) where the response status is also an error.","commonSituations":"Using a fine-grained or classic PAT created with minimal scopes; GITHUB_TOKEN from CI with restricted permissions; token scopes changed/revoked after hub was configured; enterprise instances with different default scopes.","solutions":["Regenerate or edit your GitHub token to include the required scopes (typically 'repo', plus 'gist' or 'read:org' as needed) and update it via `hub config` or $GITHUB_TOKEN.","Read the second line of the error: it names the required vs. accepted scopes from the response headers; grant exactly those.","If using SSO, authorize the token for the organization (see the X-Github-SSO header handling in the same file).","Verify with `curl -H \"Authorization: token $TOKEN\" https://api.github.com/user` and inspect the X-OAuth-Scopes header."],"exampleFix":"// before: token with no scopes\nexport GITHUB_TOKEN=ghp_minimal_token\n// after: create token with repo, read:org, gist scopes\nexport GITHUB_TOKEN=ghp_token_with_repo_readorg_gist_scopes","handlingStrategy":"validation","validationCode":"// Before calls that need scopes, verify the token's scopes:\nresp, _ := http.Get(\"https://api.github.com/user\") // with Authorization header\nscopes := resp.Header.Get(\"X-OAuth-Scopes\")\nif !strings.Contains(scopes, \"repo\") {\n    return fmt.Errorf(\"token lacks 'repo' scope; has: %s\", scopes)\n}","typeGuard":"func hasScope(header string, want string) bool {\n    for _, s := range strings.Split(header, \", \") {\n        if s == want { return true }\n    }\n    return false\n}","tryCatchPattern":"if err != nil {\n    if strings.Contains(err.Error(), \"OAuth scopes\") {\n        // prompt user to regenerate token with required scopes\n    }\n    return err\n}","preventionTips":["Create tokens with all scopes you need upfront (repo, read:org, gist).","Periodically check X-OAuth-Scopes on any API response to catch scope drift.","For CI, use fine-grained tokens and map required permissions explicitly.","Authorize the token for SSO-restricted organizations."],"tags":["oauth","authentication","http","scopes"],"backgroundTag":"oauth-insufficient-scope","analyzedSha":"5c547ed804368763064e51f3990851e267e88edd","analyzedAt":"2026-09-01T03:34:15.525Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}