larksuite/cli · error
failed to parse response: %w
Error message
failed to parse response: %w
What it means
getAppInfo calls the Lark auth API (ApplicationInfoPath) and decodes the raw HTTP body into appInfoResponse. If json.Unmarshal fails because the body is not valid JSON or does not match the struct, the error is wrapped as "failed to parse response". This distinguishes a decode-level problem from a Lark business error (resp.Code != 0), which is classified separately by classifyAppInfoErr.
Source
Thrown at cmd/auth/auth.go:161
if err != nil {
return nil, err
}
queryParams := make(larkcore.QueryParams)
queryParams.Set("lang", "zh_cn")
apiResp, err := ac.DoSDKRequest(ctx, &larkcore.ApiReq{
HttpMethod: http.MethodGet,
ApiPath: larkauth.ApplicationInfoPath(appId),
QueryParams: queryParams,
}, core.AsBot)
if err != nil {
return nil, err
}
var resp appInfoResponse
if err := json.Unmarshal(apiResp.RawBody, &resp); err != nil {
return nil, fmt.Errorf("failed to parse response: %w", err)
}
if resp.Code != 0 {
return nil, classifyAppInfoErr(apiResp.RawBody, resp.Code, resp.Msg, f, appId)
}
app := resp.Data.App
ownerOpenId := app.Owner.OwnerID
if ownerOpenId == "" {
ownerOpenId = app.CreatorID
}
var userScopes []string
for _, s := range app.Scopes {
if s.Scope == "" || !slices.Contains(s.TokenTypes, "user") {
continue
}
userScopes = append(userScopes, s.Scope)
}View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Inspect the raw body: re-run with verbose/debug logging (larkcore debug env) to see what was actually returned before the unmarshal failure.
- Check network path: bypass proxies/VPNs or fix HTTPS_PROXY settings so requests reach open.feishu.cn directly.
- Verify the app ID and endpoint: a wrong appId can hit a route returning a non-JSON error page; confirm with a manual curl of the same path.
- Upgrade or pin the lark SDK (larkcore/larkauth) and lark-cli to matching versions so the response schema matches the decoder.
Example fix
// before: opaque wrap hides body contents
return nil, fmt.Errorf("failed to parse response: %w", err)
// after: include a body snippet to diagnose proxies/HTML responses
snippet := apiResp.RawBody
if len(snippet) > 200 {
snippet = snippet[:200]
}
return nil, fmt.Errorf("failed to parse response: %w (body: %q)", err, snippet) Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight: confirm the API path returns JSON before decoding
resp, err := http.Get("https://open.feishu.cn/open-apis/auth/v3/app_info?app_id=" + appId)
if err != nil { return err }
ct := resp.Header.Get("Content-Type")
if !strings.Contains(ct, "application/json") {
return fmt.Errorf("expected JSON, got %s (status %d)", ct, resp.StatusCode)
} Type guard
func isJSONDecodeErr(err error) bool {
var syn *json.SyntaxError
var typ *json.UnmarshalTypeError
return errors.As(err, &syn) || errors.As(err, &typ)
} Try / catch
info, err := getAppInfo(ctx, f, appId)
if err != nil {
if isJSONDecodeErr(err) {
// non-JSON body: retry via a different network path or surface a proxy hint
log.Printf("API returned non-JSON body: %v", err)
return retryViaDirectConnection(ctx, appId)
}
return err
} Prevention
- Run auth commands from networks that reach open.feishu.cn without HTML interception (disable captive portals/ssl-inspection for the domain).
- Pin lark-cli and the lark SDK versions together so response schemas stay in sync.
- Validate appId format before calling to avoid route mismatch error pages.
- Check Content-Type/status of API responses before unmarshaling raw bodies.
When it happens
Trigger: Any lark-cli auth command that resolves app info (e.g. app-credential/scopes flows calling getAppInfo) when the API returns a response whose RawBody cannot be unmarshaled: an HTML login/error page, a proxy or captive-portal response, a truncated/garbled body, or an unexpected schema shape after SDK version changes.
Common situations: Corporate proxy or VPN intercepting open.feishu.cn and returning HTML; pointing the CLI at a wrong base URL or mock endpoint; an SDK/larkcore upgrade that changed the response envelope so the struct no longer matches; network middleware returning gzip/binary content.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- response parse error: %w (body: %s)
- failed to parse user info: %w
- parse range start: %w
- parse range end: %w
- parse total size: %w
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/d583a97cc98a3790.
Report an issue: GitHub.