larksuite/cli · error
Device authorization failed: HTTP %d – response not JSON
Error message
Device authorization failed: HTTP %d – response not JSON
What it means
RequestDeviceAuthorization parsed the device-authorization endpoint's body as JSON and json.Unmarshal failed. Either the server returned non-JSON (HTML error page, empty body, gateway message) or the body was truncated. The HTTP status is embedded in the message to hint at the source.
Source
Thrown at internal/auth/device_flow.go:107
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Authorization", "Basic "+basicAuth)
resp, err := httpClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
logHTTPResponse(resp)
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("Device authorization failed: read body: %v", err)
}
var data map[string]interface{}
if err := json.Unmarshal(body, &data); err != nil {
return nil, fmt.Errorf("Device authorization failed: HTTP %d – response not JSON", resp.StatusCode)
}
_, hasError := data["error"]
if resp.StatusCode >= 400 || hasError {
msg := getStr(data, "error_description")
if msg == "" {
msg = getStr(data, "error")
}
if msg == "" {
msg = "Unknown error"
}
return nil, fmt.Errorf("Device authorization failed: %s", msg)
}
expiresIn := getInt(data, "expires_in", 240)
interval := getInt(data, "interval", 5)
verificationUri := getStr(data, "verification_uri")View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Check the HTTP status in the message: 4xx/5xx from a gateway usually means the request never reached the auth service — verify network/proxy settings.
- Verify the base URL / endpoint configuration points at open.feishu.cn.
- Log or dump the raw body (before unmarshal) to see what was actually returned.
- Retry after confirming connectivity; a transient gateway page will disappear on retry.
Defensive patterns
Strategy: validation
Validate before calling
// preflight: verify the device-auth endpoint returns JSON before starting the flow
resp, _ := http.Get(deviceAuthURL)
b, _ := io.ReadAll(io.LimitReader(resp.Body, 512))
if !json.Valid(b) && resp.StatusCode != http.StatusOK {
log.Fatalf("endpoint not returning JSON (HTTP %d): %.200s", resp.StatusCode, b)
} Type guard
func isNonJSONDeviceAuthErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "response not JSON")
} Try / catch
resp, err := auth.RequestDeviceAuthorization(ctx, clientID, scopes)
if isNonJSONDeviceAuthErr(err) {
return fmt.Errorf("gateway/proxy returned non-JSON; check network and base URL: %w", err)
} Prevention
- Verify base URL and endpoint overrides point at open.feishu.cn.
- Test from inside the target network to catch proxy block pages early.
- Check the HTTP status embedded in the message to distinguish gateway vs API errors.
- Log raw response bodies when debugging auth flows.
When it happens
Trigger: json.Unmarshal(body, &data) returns an error in RequestDeviceAuthorization — e.g. an LB/gateway returns an HTML 502 page, an empty 200 body, or the endpoint is blocked and a captive portal responds.
Common situations: Corporate proxy returning an HTML block page for open.feishu.cn; wrong base URL/endpoint override pointing at a non-Lark server; gateway outage serving plain-text error pages.
Related errors
- app registration failed: HTTP %d – response not JSON
- parse response: %w
- failed to parse response: %w
- app registration failed: %s
- app registration failed: response missing device_code
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/e1c09798a4a22266.
Report an issue: GitHub.