charmbracelet/crush · warning
failed to marshal oauth token: %w
Error message
failed to marshal oauth token: %w
What it means
SetProviderAPIKey marshals the *oauth.Token to JSON for the request body. This error wraps a json.Marshal failure on the token — typically caused by a field on the token that cannot be serialized (channels, funcs, or a custom MarshalJSON that errors).
Source
Thrown at internal/client/config.go:104
kind proto.APIKeyKind
raw json.RawMessage
)
switch v := apiKey.(type) {
case string:
kind = proto.APIKeyKindString
b, err := json.Marshal(v)
if err != nil {
return fmt.Errorf("failed to marshal api key string: %w", err)
}
raw = b
case *oauth.Token:
if v == nil {
return fmt.Errorf("oauth token is nil")
}
kind = proto.APIKeyKindOAuth
b, err := json.Marshal(v)
if err != nil {
return fmt.Errorf("failed to marshal oauth token: %w", err)
}
raw = b
default:
return fmt.Errorf("unsupported api key type %T", apiKey)
}
rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/config/provider-key", id), nil, jsonBody(proto.ConfigProviderKeyRequest{
Scope: scope,
ProviderID: providerID,
Kind: kind,
APIKey: raw,
}), http.Header{"Content-Type": []string{"application/json"}})
if err != nil {
return fmt.Errorf("failed to set provider API key: %w", err)
}
defer rsp.Body.Close()
if rsp.StatusCode != http.StatusOK {
return fmt.Errorf("failed to set provider API key: status code %d", rsp.StatusCode)View on GitHub (pinned to 7944b8e522)
Solutions
- Inspect the wrapped %w error to find the offending field
- Ensure the token struct contains only JSON-serializable fields
- Remove or fix any custom MarshalJSON implementation on the token type
Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := json.Marshal(tok); err != nil {
return fmt.Errorf("oauth token not serializable: %w", err)
} Try / catch
if err := c.SetProviderAPIKey(ctx, wsID, scope, pid, tok); err != nil {
if strings.Contains(err.Error(), "marshal oauth token") {
return fmt.Errorf("token contains unsupported fields: %w", err)
}
return err
} Prevention
- Use the standard oauth.Token type from the library, not custom structs
- Keep token structs free of channels, funcs, and custom failing marshalers
When it happens
Trigger: Calling SetProviderAPIKey with an *oauth.Token whose MarshalJSON (or an unexported field with a custom marshaler) returns an error.
Common situations: A custom or third-party oauth.Token type with unsupported field types, or a corrupted/populated-with-functions token struct.
Related errors
- failed to marshal api key string: %w
- failed to decode MCP auth URL: %w
- marshal request: %w
- github copilot not available
- ${ErrorDescription}
AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29).
Data as JSON: /api/errors/aea2a7f1abbe46f8.
Report an issue: GitHub.