{"record":{"id":"141c68b28a484c39","repo":"github/github-mcp-server","slug":"failed-to-get-github-client-w","errorCode":null,"errorMessage":"failed to get GitHub client: %w","messagePattern":"failed to get GitHub client: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/github/actions.go","lineNumber":355,"sourceCode":"\n\t\t\tmethod, err := RequiredParam[string](args, \"method\")\n\t\t\tif err != nil {\n\t\t\t\treturn utils.NewToolResultError(err.Error()), nil, nil\n\t\t\t}\n\n\t\t\tresourceID, err := OptionalParam[string](args, \"resource_id\")\n\t\t\tif err != nil {\n\t\t\t\treturn utils.NewToolResultError(err.Error()), nil, nil\n\t\t\t}\n\n\t\t\tpagination, err := OptionalPaginationParams(args)\n\t\t\tif err != nil {\n\t\t\t\treturn utils.NewToolResultError(err.Error()), nil, nil\n\t\t\t}\n\n\t\t\tclient, err := deps.GetClient(ctx)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, nil, fmt.Errorf(\"failed to get GitHub client: %w\", err)\n\t\t\t}\n\n\t\t\t// attachIFC adds the IFC label to a successful Actions result when\n\t\t\t// IFC labels are enabled. Workflow definitions, runs, jobs,\n\t\t\t// artifacts and logs echo attacker-influenceable run output, so\n\t\t\t// integrity is untrusted; confidentiality follows repo visibility.\n\t\t\tattachIFC := func(r *mcp.CallToolResult) *mcp.CallToolResult {\n\t\t\t\treturn attachRepoVisibilityIFCLabel(ctx, deps, client, owner, repo, r, ifc.LabelActionsResult)\n\t\t\t}\n\n\t\t\tvar resourceIDInt int64\n\t\t\tvar parseErr error\n\t\t\tswitch method {\n\t\t\tcase actionsMethodListWorkflows:\n\t\t\t\t// Do nothing, no resource ID needed\n\t\t\tcase actionsMethodListWorkflowRuns:\n\t\t\t\t// resource_id is optional for list_workflow_runs\n\t\t\t\t// If not provided, list all workflow runs in the repository","sourceCodeStart":337,"sourceCodeEnd":373,"githubUrl":"https://github.com/github/github-mcp-server/blob/0ea1f775a7c73eff1bd2e25904d01136756bbfe2/pkg/github/actions.go#L337-L373","documentation":"Returned by the list_actions_resources tool handler (pkg/github/actions.go:355) when deps.GetClient(ctx) fails before any API call is made. With BaseDeps (local stdio mode) GetClient cannot fail, so this error only occurs in the request-scoped (remote/hosted HTTP) deployment where GetClient re-creates a client per call: it fails with 'no token info in context', 'failed to get base REST URL', 'failed to get upload URL', or 'failed to create REST client' (pkg/github/dependencies.go:308-334).","triggerScenarios":"Calling list_actions_resources on the remote server variant when the request context lacks TokenInfo (no Authorization header propagated), when GHES host configuration (GH_HOST / GITHUB_API_HOST / GITHUB_UPLOAD_HOST) fails to parse into valid URLs, or when gogithub.NewClient rejects the enterprise URLs.","commonSituations":"Self-hosting the HTTP transport and forgetting the Authorization: Bearer header; misconfigured GHES env vars (trailing slashes, missing /api/v3, unreachable host scheme); load balancers stripping auth headers; embedding the server without attaching token info to the context.","solutions":["Send a valid PAT on every HTTP request: Authorization: Bearer <token> so the middleware can populate TokenInfo","Verify GHES env vars: GITHUB_API_HOST like https://ghes.example.com/api/v3 and matching upload host","Check proxies/LBs forward the Authorization header unmodified","If embedding, attach the token before invoking the tool: ctx = ghcontext.WithTokenInfo(ctx, &ghcontext.TokenInfo{Token: t})"],"exampleFix":"// before (remote-server client)\nreq, _ := http.NewRequest(http.MethodPost, srv.URL, body)\nreq.Header.Set(\"Accept\", \"application/json\")\n// tool call -> \"failed to get GitHub client: no token info in context\"\n\n// after\nreq, _ := http.NewRequest(http.MethodPost, srv.URL, body)\nreq.Header.Set(\"Authorization\", \"Bearer \"+pat)\nreq.Header.Set(\"Accept\", \"application/json, text/event-stream\")","handlingStrategy":"validation","validationCode":"// MCP HTTP client: assert auth is wired before any tool call\nreq.Header.Set(\"Authorization\", \"Bearer \"+pat)\nif req.Header.Get(\"Authorization\") == \"\" {\n    return errors.New(\"missing PAT: remote server requires Authorization header\")\n}\n\n// Embedder: assert token info is in context\nif _, ok := ghcontext.GetTokenInfo(ctx); !ok {\n    ctx = ghcontext.WithTokenInfo(ctx, &ghcontext.TokenInfo{Token: pat})\n}","typeGuard":null,"tryCatchPattern":"client, err := deps.GetClient(ctx)\nif err != nil {\n    if strings.Contains(err.Error(), \"no token info in context\") {\n        return fixAuthHeaderThenRetry() // client-side config, not GitHub\n    }\n    return err // GHES URL misconfiguration: check GITHUB_API_HOST / upload host\n}","preventionTips":["Send Authorization: Bearer on every request to the remote server","Ensure auth middleware runs before tool dispatch so TokenInfo reaches GetClient","Keep GHES env vars valid absolute URLs (api/v3 suffix on the API host)","Smoke-test with get_me after any deployment change"],"tags":["configuration","auth","token","ghes","go"],"backgroundTag":null,"analyzedSha":"0ea1f775a7c73eff1bd2e25904d01136756bbfe2","analyzedAt":"2026-08-15T18:10:19.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}