{"record":{"id":"c835472fe2d6d59e","repo":"larksuite/cli","slug":"decode-application-response-w","errorCode":null,"errorMessage":"decode application response: %w","messagePattern":"decode application response: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/appmeta/app_callbacks.go","lineNumber":35,"sourceCode":"// weak-dependency skip. Identity must be bot: the endpoint is app-level.\nfunc FetchSubscribedCallbacks(ctx context.Context, client APIClient, appID string) ([]string, error) {\n\tpath := fmt.Sprintf(\"/open-apis/application/v6/applications/%s?lang=zh_cn\", appID)\n\traw, err := client.CallAPI(ctx, \"GET\", path, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tvar envelope struct {\n\t\tData struct {\n\t\t\tApp struct {\n\t\t\t\tCallbackInfo *struct {\n\t\t\t\t\tSubscribedCallbacks []string `json:\"subscribed_callbacks\"`\n\t\t\t\t} `json:\"callback_info\"`\n\t\t\t} `json:\"app\"`\n\t\t} `json:\"data\"`\n\t}\n\tif err := json.Unmarshal(raw, &envelope); err != nil {\n\t\treturn nil, fmt.Errorf(\"decode application response: %w\", err)\n\t}\n\t// callback_info also carries callback_type (e.g. \"websocket\"); it is\n\t// intentionally not parsed or validated. Feishu open-platform callbacks are\n\t// delivered over WebSocket only (confirmed), matching the CLI's WebSocket\n\t// event source, so subscribed_callbacks alone is sufficient for the precheck.\n\t// Revisit and validate callback_type if non-WebSocket delivery ever appears.\n\tcallbacks := []string{}\n\tif ci := envelope.Data.App.CallbackInfo; ci != nil {\n\t\tcallbacks = append(callbacks, ci.SubscribedCallbacks...)\n\t}\n\treturn callbacks, nil\n}\n","sourceCodeStart":17,"sourceCodeEnd":48,"githubUrl":"https://github.com/larksuite/cli/blob/7fd6ef3c07182257ce776cdc5a614e122d5bd4b3/internal/appmeta/app_callbacks.go#L17-L48","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before: ignoring the wrapped cause\nif err := fetch(); err != nil { return err }\n// after: surface the decode cause\nvar derr *json.UnmarshalTypeError\nif errors.As(err, &derr) { log.Printf(\"field %s: %v\", derr.Field, derr) }","handlingStrategy":"try-catch","validationCode":"// pre-check the response looks like JSON before decoding\nif len(raw) > 0 && raw[0] != '{' && raw[0] != '[' {\n  return fmt.Errorf(\"non-JSON response: %.100s\", raw)\n}","typeGuard":null,"tryCatchPattern":"items, err := meta.FetchSubscribedCallbacks(ctx, raw)\nif err != nil {\n  var jsonErr *json.SyntaxError\n  if errors.As(err, &jsonErr) { /* log raw body, retry with backoff */ }\n  return err\n}","preventionTips":["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"],"tags":["json","decode","api","appmeta"],"backgroundTag":"json-response-decode-failed","analyzedSha":"7fd6ef3c07182257ce776cdc5a614e122d5bd4b3","analyzedAt":"2026-09-04T21:17:44.649Z","contentChangedAt":"2026-09-04T21:17:44.649Z","schemaVersion":2},"datasetVersion":"2026-09-12T02:17:10.037Z"}