{"record":{"id":"a19130b4bf208282","repo":"gastownhall/beads","slug":"graphql-request-failed-w","errorCode":null,"errorMessage":"GraphQL request failed: %w","messagePattern":"GraphQL request failed: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/gitlab/client.go","lineNumber":511,"sourceCode":"\t}\n\n\treturn &milestone, nil\n}\n\n// GraphQL support for work item hierarchy (Issue → Task parent-child).\n\n// graphqlRequest executes a GraphQL query against the GitLab instance.\nfunc (c *Client) graphqlRequest(ctx context.Context, query string, variables map[string]interface{}) (json.RawMessage, error) {\n\tbody := map[string]interface{}{\"query\": query}\n\tif len(variables) > 0 {\n\t\tbody[\"variables\"] = variables\n\t}\n\n\t// GraphQL endpoint is at /api/graphql (not under /api/v4/)\n\turlStr := c.BaseURL + \"/api/graphql\"\n\trespBody, _, err := c.doRequest(ctx, http.MethodPost, urlStr, body)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"GraphQL request failed: %w\", err)\n\t}\n\n\tvar result struct {\n\t\tData   json.RawMessage `json:\"data\"`\n\t\tErrors []struct {\n\t\t\tMessage string `json:\"message\"`\n\t\t} `json:\"errors\"`\n\t}\n\tif err := json.Unmarshal(respBody, &result); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse GraphQL response: %w\", err)\n\t}\n\tif len(result.Errors) > 0 {\n\t\treturn nil, fmt.Errorf(\"GraphQL error: %s\", result.Errors[0].Message)\n\t}\n\treturn result.Data, nil\n}\n\n// WorkItem represents a GitLab work item from the GraphQL API.","sourceCodeStart":493,"sourceCodeEnd":529,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/gitlab/client.go#L493-L529","documentation":"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).","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before: base URL missing scheme\nclient := &Client{BaseURL: \"gitlab.example.com\"}\n// after\nclient := &Client{BaseURL: \"https://gitlab.example.com\"}","handlingStrategy":"validation","validationCode":"u, err := url.Parse(client.BaseURL)\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return fmt.Errorf(\"BaseURL %q must include scheme and host\", client.BaseURL)\n}\n// optionally probe the endpoint\nresp, err := http.Post(client.BaseURL+\"/api/graphql\", \"application/json\", strings.NewReader(\"{}\"))","typeGuard":null,"tryCatchPattern":"data, err := client.CreateTaskWorkItem(ctx, req)\nif err != nil {\n    var netErr net.Error\n    if errors.As(err, &netErr) || strings.Contains(err.Error(), \"GraphQL request failed\") {\n        // retry with backoff or fail fast on config\n    }\n    return err\n}","preventionTips":["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."],"tags":["gitlab","graphql","network","http-request"],"backgroundTag":"http-request-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}