larksuite/cli · error
decode application response: %w
Error message
decode application response: %w
What it means
FetchSubscribedCallbacks in internal/appmeta fetches an application's subscribed callbacks from the Lark open-platform API and unmarshals the raw response into a typed envelope. This error wraps any json.Unmarshal failure decoding that response, preserving the underlying syntax/type error via %w.
Source
Thrown at internal/appmeta/app_callbacks.go:35
// weak-dependency skip. Identity must be bot: the endpoint is app-level.
func FetchSubscribedCallbacks(ctx context.Context, client APIClient, appID string) ([]string, error) {
path := fmt.Sprintf("/open-apis/application/v6/applications/%s?lang=zh_cn", appID)
raw, err := client.CallAPI(ctx, "GET", path, nil)
if err != nil {
return nil, err
}
var envelope struct {
Data struct {
App struct {
CallbackInfo *struct {
SubscribedCallbacks []string `json:"subscribed_callbacks"`
} `json:"callback_info"`
} `json:"app"`
} `json:"data"`
}
if err := json.Unmarshal(raw, &envelope); err != nil {
return nil, fmt.Errorf("decode application response: %w", err)
}
// callback_info also carries callback_type (e.g. "websocket"); it is
// intentionally not parsed or validated. Feishu open-platform callbacks are
// delivered over WebSocket only (confirmed), matching the CLI's WebSocket
// event source, so subscribed_callbacks alone is sufficient for the precheck.
// Revisit and validate callback_type if non-WebSocket delivery ever appears.
callbacks := []string{}
if ci := envelope.Data.App.CallbackInfo; ci != nil {
callbacks = append(callbacks, ci.SubscribedCallbacks...)
}
return callbacks, nil
}
View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Inspect the wrapped cause (%w) to distinguish invalid JSON from type mismatch
- Log/print the raw response body to see what was actually returned
- Check whether an auth gateway returned an HTML error page or non-200 body
- Upgrade/verify the CLI version matches the current app_versions API schema
Example fix
// before: ignoring the wrapped cause
if err := fetch(); err != nil { return err }
// after: surface the decode cause
var derr *json.UnmarshalTypeError
if errors.As(err, &derr) { log.Printf("field %s: %v", derr.Field, derr) } Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check the response looks like JSON before decoding
if len(raw) > 0 && raw[0] != '{' && raw[0] != '[' {
return fmt.Errorf("non-JSON response: %.100s", raw)
} Try / catch
items, err := meta.FetchSubscribedCallbacks(ctx, raw)
if err != nil {
var jsonErr *json.SyntaxError
if errors.As(err, &jsonErr) { /* log raw body, retry with backoff */ }
return err
} Prevention
- Log the raw response body on any fetch failure
- Check HTTP status and content-type before trusting the body
- Detect proxy/HTML error pages in tests with mock fixtures
- Pin CLI/API versions in environments where the schema may drift
When it happens
Trigger: The HTTP response body returned by the application API is not valid JSON, or its structure diverges from the envelope (e.g. data.app is a different shape) so unmarshal into the anonymous struct fails.
Common situations: A proxy or captive portal returning HTML instead of JSON; API version changes altering the payload shape; the fetch helper receiving a truncated body on network interruption.
Related errors
- decode app_versions response: %w
- connection check: decode: %w (body=%s)
- lark-cli stdout was not JSON: {snippet}
- lark-cli returned a non-object JSON payload
- malformed config
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/c835472fe2d6d59e.
Report an issue: GitHub.