{"record":{"id":"31f5d05567def467","repo":"mislav/hub","slug":"api-error-s","errorCode":null,"errorMessage":"API error: %s","messagePattern":"API error: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"github/client.go","lineNumber":964,"sourceCode":"\tresponseData := struct {\n\t\tData   interface{}\n\t\tErrors []struct {\n\t\t\tMessage string\n\t\t}\n\t}{\n\t\tData: data,\n\t}\n\terr = resp.Unmarshal(&responseData)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif len(responseData.Errors) > 0 {\n\t\tmessages := []string{}\n\t\tfor _, e := range responseData.Errors {\n\t\t\tmessages = append(messages, e.Message)\n\t\t}\n\t\treturn fmt.Errorf(\"API error: %s\", strings.Join(messages, \"; \"))\n\t}\n\treturn nil\n}\n\nfunc (client *Client) CurrentUser() (user *User, err error) {\n\tapi, err := client.simpleAPI()\n\tif err != nil {\n\t\treturn\n\t}\n\n\tres, err := api.Get(\"user\")\n\tif err = checkStatus(200, \"getting current user\", res, err); err != nil {\n\t\treturn\n\t}\n\n\tuser = &User{}\n\terr = res.Unmarshal(user)\n\treturn","sourceCodeStart":946,"sourceCodeEnd":982,"githubUrl":"https://github.com/mislav/hub/blob/5c547ed804368763064e51f3990851e267e88edd/github/client.go#L946-L982","documentation":"This is the GraphQL error formatter: when the API's JSON response contains a non-empty `errors` array, each error's Message is joined with '; ' and returned as 'API error: <messages>'. It is raised by the shared GraphQL helper after a request whose HTTP transport succeeded but whose query was rejected or partially failed.","triggerScenarios":"Any GraphQL query/mutation through the client where responseData.Errors is non-empty: invalid query fields, missing nodes (nulls with messages), rate limit errors, insufficient permission on a resource, or malformed variables.","commonSituations":"Querying a repo the token can't see via GraphQL (returns errors not 404); schema drift after GitHub API changes; exceeding rate limits; requesting fields that need different scopes (e.g. SSO-restricted org data).","solutions":["Read the joined message(s) after 'API error: ' — they name the failing field/reason directly.","Fix the query/mutation fields or variables indicated by the message.","If it's a permission/SSO message, re-authorize the token for the org (see the X-Github-Sso URL flow).","If it's rate limiting, wait for the reset or check `X-RateLimit-Remaining` before retrying."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func isGraphQLError(err error) bool { return strings.HasPrefix(err.Error(), \"API error: \") }","tryCatchPattern":"if err != nil && strings.HasPrefix(err.Error(), \"API error: \") {\n    msgs := strings.Split(strings.TrimPrefix(err.Error(), \"API error: \"), \"; \")\n    for _, m := range msgs { log.Printf(\"graphql: %s\", m) }\n}","preventionTips":["Validate GraphQL queries against the current schema; GitHub deprecates/changes fields.","Check rate-limit headers before large query batches.","Ensure the token is SSO-authorized and scoped for every org queried.","Handle partial results: GraphQL can return data AND errors simultaneously."],"tags":["github-api","graphql","api-error"],"backgroundTag":"graphql-errors-response","analyzedSha":"5c547ed804368763064e51f3990851e267e88edd","analyzedAt":"2026-09-01T03:34:15.525Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}