gastownhall/beads · error
GraphQL request failed: %w
Error message
GraphQL request failed: %w
What it means
graphqlRequest performs POSTs to the GitLab GraphQL endpoint (/api/graphql) and wraps any transport-level failure from doRequest with this message. It means the HTTP request itself failed — connection refused, TLS error, timeout, or non-reachable server — not a GraphQL-level error. It is the entry point for the work item hierarchy APIs (getTaskWorkItemTypeID, CreateTaskWorkItem, GetWorkItemGID).
Source
Thrown at internal/gitlab/client.go:511
}
return &milestone, nil
}
// GraphQL support for work item hierarchy (Issue → Task parent-child).
// graphqlRequest executes a GraphQL query against the GitLab instance.
func (c *Client) graphqlRequest(ctx context.Context, query string, variables map[string]interface{}) (json.RawMessage, error) {
body := map[string]interface{}{"query": query}
if len(variables) > 0 {
body["variables"] = variables
}
// GraphQL endpoint is at /api/graphql (not under /api/v4/)
urlStr := c.BaseURL + "/api/graphql"
respBody, _, err := c.doRequest(ctx, http.MethodPost, urlStr, body)
if err != nil {
return nil, fmt.Errorf("GraphQL request failed: %w", err)
}
var result struct {
Data json.RawMessage `json:"data"`
Errors []struct {
Message string `json:"message"`
} `json:"errors"`
}
if err := json.Unmarshal(respBody, &result); err != nil {
return nil, fmt.Errorf("failed to parse GraphQL response: %w", err)
}
if len(result.Errors) > 0 {
return nil, fmt.Errorf("GraphQL error: %s", result.Errors[0].Message)
}
return result.Data, nil
}
// WorkItem represents a GitLab work item from the GraphQL API.View on GitHub (pinned to 71377f2769)
Solutions
- Check the wrapped error (%w chain) to see the underlying cause (connection refused, TLS, timeout).
- Verify c.BaseURL is correct and that <BaseURL>/api/graphql is reachable (curl -X POST).
- Confirm the GitLab instance supports the GraphQL API and work items (GitLab 16+ for work items).
- Check network/proxy configuration and TLS trust for the GitLab host.
Example fix
// before: base URL missing scheme
client := &Client{BaseURL: "gitlab.example.com"}
// after
client := &Client{BaseURL: "https://gitlab.example.com"} Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(client.BaseURL)
if err != nil || u.Scheme == "" || u.Host == "" {
return fmt.Errorf("BaseURL %q must include scheme and host", client.BaseURL)
}
// optionally probe the endpoint
resp, err := http.Post(client.BaseURL+"/api/graphql", "application/json", strings.NewReader("{}")) Try / catch
data, err := client.CreateTaskWorkItem(ctx, req)
if err != nil {
var netErr net.Error
if errors.As(err, &netErr) || strings.Contains(err.Error(), "GraphQL request failed") {
// retry with backoff or fail fast on config
}
return err
} Prevention
- Set BaseURL with scheme and host (https://gitlab.example.com), no trailing path.
- Confirm the GitLab version supports the GraphQL work item APIs before use.
- Ensure the API host is reachable from the deployment environment (firewall/proxy).
- Use retries with backoff for transient network failures.
When it happens
Trigger: Any call to getTaskWorkItemTypeID, CreateTaskWorkItem, or GetWorkItemGID where c.doRequest fails: wrong BaseURL, network outage, TLS certificate rejection, authentication middleware rejecting the POST, or the server not exposing /api/graphql (older GitLab versions).
Common situations: Pointing BaseURL at a host that only serves the REST API; running against GitLab instances older than GraphQL work item support; corporate proxies blocking POST to /api/graphql; expired tokens causing middleware-level connection aborts.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- request failed (attempt %d/%d): %w
- failed to read response (attempt %d/%d): %w
- max retries (%d) exceeded: %w
- failed to parse issues response: %w
- pagination limit exceeded: stopped after %d pages
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/a19130b4bf208282.
Report an issue: GitHub.