mislav/hub · error
API error: %s
Error message
API error: %s
What it means
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.
Source
Thrown at github/client.go:964
responseData := struct {
Data interface{}
Errors []struct {
Message string
}
}{
Data: data,
}
err = resp.Unmarshal(&responseData)
if err != nil {
return err
}
if len(responseData.Errors) > 0 {
messages := []string{}
for _, e := range responseData.Errors {
messages = append(messages, e.Message)
}
return fmt.Errorf("API error: %s", strings.Join(messages, "; "))
}
return nil
}
func (client *Client) CurrentUser() (user *User, err error) {
api, err := client.simpleAPI()
if err != nil {
return
}
res, err := api.Get("user")
if err = checkStatus(200, "getting current user", res, err); err != nil {
return
}
user = &User{}
err = res.Unmarshal(user)
returnView on GitHub (pinned to 5c547ed804)
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.
Defensive patterns
Strategy: try-catch
Type guard
func isGraphQLError(err error) bool { return strings.HasPrefix(err.Error(), "API error: ") } Try / catch
if err != nil && strings.HasPrefix(err.Error(), "API error: ") {
msgs := strings.Split(strings.TrimPrefix(err.Error(), "API error: "), "; ")
for _, m := range msgs { log.Printf("graphql: %s", m) }
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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).
Related errors
- Error creating fork: %s already exists on %s
- Error: that fork is not available anymore
- %s\nAre you sure that %s exists?
- Unable to find release with tag name `%s'
- Error %s: %s
AI-assisted analysis of mislav/hub@5c547ed804 (2026-09-01).
Data as JSON: /api/errors/31f5d05567def467.
Report an issue: GitHub.