{"record":{"id":"962ae452f1306b2b","repo":"gastownhall/beads","slug":"failed-to-create-request-w-962ae4","errorCode":null,"errorMessage":"failed to create request: %w","messagePattern":"failed to create request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/linear/client.go","lineNumber":366,"sourceCode":"\n// executeOnce performs the actual HTTP request loop with rate-limit retries.\n// Returns the response data, the last HTTP status code encountered, and any error.\nfunc (c *Client) executeOnce(ctx context.Context, req *GraphQLRequest) (json.RawMessage, int, error) {\n\tbody, err := json.Marshal(req)\n\tif err != nil {\n\t\treturn nil, 0, fmt.Errorf(\"failed to marshal request: %w\", err)\n\t}\n\n\tvar lastErr error\n\tvar lastStatus int\n\tfor attempt := 0; attempt <= MaxRetries; attempt++ {\n\t\tif rlErr := c.circuitBreakerError(); rlErr != nil {\n\t\t\treturn nil, lastStatus, rlErr\n\t\t}\n\n\t\thttpReq, err := http.NewRequestWithContext(ctx, \"POST\", c.Endpoint, bytes.NewReader(body))\n\t\tif err != nil {\n\t\t\treturn nil, 0, fmt.Errorf(\"failed to create request: %w\", err)\n\t\t}\n\n\t\thttpReq.Header.Set(\"Content-Type\", \"application/json\")\n\t\tauthValue, err := c.authHeader()\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\thttpReq.Header.Set(\"Authorization\", authValue)\n\n\t\tresp, err := c.HTTPClient.Do(httpReq)\n\t\tif err != nil {\n\t\t\tlastErr = fmt.Errorf(\"request failed (attempt %d/%d): %w\", attempt+1, MaxRetries+1, err)\n\t\t\tcontinue\n\t\t}\n\n\t\trespBody, err := io.ReadAll(io.LimitReader(resp.Body, MaxResponseSize))\n\t\t_ = resp.Body.Close() // Best effort: HTTP body close; connection may be reused regardless\n\t\tif err != nil {","sourceCodeStart":348,"sourceCodeEnd":384,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/linear/client.go#L348-L384","documentation":"executeOnce builds the outbound POST with http.NewRequestWithContext against the client's Endpoint. If request construction fails (typically a malformed or unparseable URL/endpoint), it returns 'failed to create request' wrapped around the underlying error. This happens before sending, so no HTTP exchange occurred.","triggerScenarios":"Any Execute call where c.Endpoint is empty, contains spaces/control characters, or otherwise fails http.NewRequestWithContext URL parsing (url.Parse error).","commonSituations":"Misconfigured LINEAR endpoint env var (empty, typo like 'linear.api.com' without scheme is actually fine for Parse, but a URL with spaces or invalid characters is not); config interpolation that produced an empty endpoint; environment variable truncated by shell quoting.","solutions":["Print and inspect the wrapped error plus the configured Endpoint value","Set Endpoint to a valid absolute URL, e.g. https://api.linear.app/graphql","Check the env var/config feeding Endpoint for empty values or stray characters/whitespace","Quote the endpoint when exporting it in shell to avoid truncation"],"exampleFix":"// before\nclient := &linear.Client{Endpoint: os.Getenv(\"LINEAR_ENDPOINT\")} // may be \"\"\n// after\nendpoint := os.Getenv(\"LINEAR_ENDPOINT\")\nif endpoint == \"\" { endpoint = \"https://api.linear.app/graphql\" }\nif _, err := url.Parse(endpoint); err != nil { return err }\nclient := &linear.Client{Endpoint: endpoint}","handlingStrategy":"validation","validationCode":"u, err := url.Parse(endpoint)\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n\treturn fmt.Errorf(\"invalid Linear endpoint %q\", endpoint)\n}","typeGuard":"func validEndpoint(s string) bool {\n\tu, err := url.Parse(s)\n\treturn err == nil && (u.Scheme == \"http\" || u.Scheme == \"https\") && u.Host != \"\" && url.PathEscape(s) == s || (u.Scheme == \"https\" && u.Host != \"\")\n}","tryCatchPattern":"data, err := client.Execute(ctx, req)\nif err != nil {\n\tif strings.Contains(err.Error(), \"failed to create request\") {\n\t\treturn fmt.Errorf(\"misconfigured endpoint %q: %w\", endpoint, err)\n\t}\n\treturn err\n}","preventionTips":["Default the endpoint to https://api.linear.app/graphql when unset","Trim whitespace from endpoint values read from env/config","Fail fast at startup by constructing one probe request to validate the endpoint","Quote env vars in shell (export LINEAR_ENDPOINT=\"...\") to avoid truncated values"],"tags":["http","configuration","url","linear"],"backgroundTag":"invalid-endpoint-url","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}