{"record":{"id":"979c88448890cdee","repo":"charmbracelet/crush","slug":"failed-to-decode-import-copilot-response-w","errorCode":null,"errorMessage":"failed to decode import copilot response: %w","messagePattern":"failed to decode import copilot response: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/client/config.go","lineNumber":143,"sourceCode":"}\n\n// ImportCopilot attempts to import a GitHub Copilot token on the\n// server.\nfunc (c *Client) ImportCopilot(ctx context.Context, id string) (*oauth.Token, bool, error) {\n\trsp, err := c.post(ctx, fmt.Sprintf(\"/workspaces/%s/config/import-copilot\", id), nil, nil, nil)\n\tif err != nil {\n\t\treturn nil, false, fmt.Errorf(\"failed to import copilot: %w\", err)\n\t}\n\tdefer rsp.Body.Close()\n\tif rsp.StatusCode != http.StatusOK {\n\t\treturn nil, false, fmt.Errorf(\"failed to import copilot: status code %d\", rsp.StatusCode)\n\t}\n\tvar result struct {\n\t\tToken   *oauth.Token `json:\"token\"`\n\t\tSuccess bool         `json:\"success\"`\n\t}\n\tif err := json.NewDecoder(rsp.Body).Decode(&result); err != nil {\n\t\treturn nil, false, fmt.Errorf(\"failed to decode import copilot response: %w\", err)\n\t}\n\treturn result.Token, result.Success, nil\n}\n\n// RefreshOAuthToken refreshes an OAuth token for a provider on the\n// server.\nfunc (c *Client) RefreshOAuthToken(ctx context.Context, id string, scope config.Scope, providerID string) error {\n\trsp, err := c.post(ctx, fmt.Sprintf(\"/workspaces/%s/config/refresh-oauth\", id), nil, jsonBody(struct {\n\t\tScope      config.Scope `json:\"scope\"`\n\t\tProviderID string       `json:\"provider_id\"`\n\t}{Scope: scope, ProviderID: providerID}), http.Header{\"Content-Type\": []string{\"application/json\"}})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to refresh OAuth token: %w\", err)\n\t}\n\tdefer rsp.Body.Close()\n\tif rsp.StatusCode != http.StatusOK {\n\t\treturn fmt.Errorf(\"failed to refresh OAuth token: status code %d\", rsp.StatusCode)\n\t}","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/charmbracelet/crush/blob/7944b8e52225d8805e31eacbf7ef24856b0dfb7a/internal/client/config.go#L125-L161","documentation":"After a 200 response, ImportCopilot decodes the JSON body containing the imported token and success flag. If the body is not valid JSON or does not match the expected shape, this error wraps the decode failure.","triggerScenarios":"Server returns 200 with malformed, empty, or non-JSON body for import-copilot (e.g. a proxy intercepting the response, or server bug returning an error page with 200).","commonSituations":"Reverse proxy or captive portal returning HTML with status 200; server/client version mismatch changing the response schema; truncated response.","solutions":["Inspect the wrapped %w error and capture the raw response body for diagnosis","Check whether a proxy or middleware is rewriting the response","Ensure client and server versions are compatible","Retry; if persistent, report a server bug returning invalid JSON with 200"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":"// sanity-check the endpoint returns JSON before decoding\ndump, _ := c.ImportCopilot(ctx, wsID) // if this errors with decode, log raw body via server logs","typeGuard":"func isJSONContentType(h http.Header) bool {\n    return strings.Contains(h.Get(\"Content-Type\"), \"application/json\")\n}","tryCatchPattern":"tok, ok, err := c.ImportCopilot(ctx, wsID)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to decode\") {\n        // likely a proxy or server bug returning non-JSON with 200\n        return diagnoseRawResponse(ctx, wsID)\n    }\n    return err\n}","preventionTips":["Bypass or check proxies/captive portals that rewrite responses","Keep client and server schemas in sync (same release train)","Log the raw body on decode failures for debugging"],"tags":["json","decode","http"],"backgroundTag":"json-decode-failed","analyzedSha":"7944b8e52225d8805e31eacbf7ef24856b0dfb7a","analyzedAt":"2026-08-29T12:48:59.079Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}