{"record":{"id":"1df2fe55099c4edc","repo":"charmbracelet/crush","slug":"create-request-w","errorCode":null,"errorMessage":"create request: %w","messagePattern":"create request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/oauth/hyper/device.go","lineNumber":48,"sourceCode":"type TokenResponse struct {\n\tRefreshToken     string `json:\"refresh_token,omitempty\"`\n\tUserID           string `json:\"user_id\"`\n\tOrganizationID   string `json:\"organization_id\"`\n\tOrganizationName string `json:\"organization_name\"`\n\tError            string `json:\"error,omitempty\"`\n\tErrorDescription string `json:\"error_description,omitempty\"`\n}\n\n// InitiateDeviceAuth calls the /device/auth endpoint to start the device flow.\nfunc InitiateDeviceAuth(ctx context.Context) (*DeviceAuthResponse, error) {\n\turl := hyper.BaseURL() + \"/device/auth\"\n\n\treq, err := http.NewRequestWithContext(\n\t\tctx, http.MethodPost, url,\n\t\tstrings.NewReader(fmt.Sprintf(`{\"device_name\":%q}`, deviceName())),\n\t)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"create request: %w\", err)\n\t}\n\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"User-Agent\", \"crush\")\n\n\tclient := &http.Client{Timeout: 30 * time.Second}\n\tresp, err := client.Do(req)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"execute request: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tbody, err := io.ReadAll(io.LimitReader(resp.Body, 1<<20))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"read response: %w\", err)\n\t}\n\n\tif resp.StatusCode != http.StatusOK {","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/oauth/hyper/device.go#L30-L66","documentation":"InitiateDeviceAuth builds the HTTP POST to the Hyper OAuth device endpoint with a JSON body containing the device name. If http.NewRequestWithContext itself fails (malformed URL or invalid reader), the error is wrapped as \"create request\". This is a construction-time failure — no network I/O has happened yet.","triggerScenarios":"http.NewRequestWithContext returns an error, practically always because the configured base URL plus path forms an invalid URL (unparsable scheme/host, control characters) or a bad context value.","commonSituations":"Misconfigured endpoint URL in settings/env (typo, empty, or containing whitespace/newline); an interceptor or test harness supplying a bogus URL; malformed context key affecting header interpolation.","solutions":["Print/inspect the full URL string passed to InitiateDeviceAuth and fix invalid characters or empty scheme","Verify the endpoint configuration source (env var, config file) for typos","If a proxy base URL is configurable, validate it parses with url.Parse before calling","Retry is pointless here — correct the configuration and call again"],"exampleFix":"// before\nu := os.Getenv(\"HYPER_API_URL\")\nauth, err := InitiateDeviceAuth(ctx, client, u)\n// after\nu := os.Getenv(\"HYPER_API_URL\")\nif _, err := url.Parse(u); err != nil || u == \"\" {\n    return fmt.Errorf(\"invalid HYPER_API_URL: %q\", u)\n}\nauth, err := InitiateDeviceAuth(ctx, client, u)","handlingStrategy":"validation","validationCode":"func validateEndpoint(base string) error {\n    if base == \"\" { return fmt.Errorf(\"endpoint empty\") }\n    u, err := url.Parse(base)\n    if err != nil { return err }\n    if u.Scheme != \"https\" || u.Host == \"\" { return fmt.Errorf(\"bad endpoint: %q\", base) }\n    return nil\n}\n// call before InitiateDeviceAuth","typeGuard":null,"tryCatchPattern":"auth, err := InitiateDeviceAuth(ctx, client, endpoint)\nif err != nil && strings.Contains(err.Error(), \"create request\") {\n    return fmt.Errorf(\"misconfigured Hyper endpoint %q: %w\", endpoint, err)\n}","preventionTips":["Validate the endpoint URL with url.Parse before constructing requests","Reject URLs containing whitespace, newlines, or control characters","Log the resolved full URL when configuration errors occur"],"tags":["oauth","device-flow","http","hyper","request-construction"],"backgroundTag":"invalid-request-url","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}