{"record":{"id":"7c14c7dd91fae8bf","repo":"chenhg5/cc-connect","slug":"cloud-web-preview-ack-timeout","errorCode":null,"errorMessage":"cloud_web: preview_ack timeout","messagePattern":"cloud_web: preview_ack timeout","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/cloud-web/gateway.go","lineNumber":316,"sourceCode":"\t}\n\treturn nil\n}\n\nfunc (t *gatewayTransport) waitPreviewAck(refID string, timeout time.Duration) (string, error) {\n\tch := make(chan string, 1)\n\tt.previewMu.Lock()\n\tt.previewRequests[refID] = ch\n\tt.previewMu.Unlock()\n\tdefer func() {\n\t\tt.previewMu.Lock()\n\t\tdelete(t.previewRequests, refID)\n\t\tt.previewMu.Unlock()\n\t}()\n\tselect {\n\tcase handle := <-ch:\n\t\treturn handle, nil\n\tcase <-time.After(timeout):\n\t\treturn \"\", fmt.Errorf(\"cloud_web: preview_ack timeout\")\n\t}\n}\n\n// previewWaiter is implemented by transports that support async preview_ack.\ntype previewWaiter interface {\n\twaitPreviewAck(refID string, timeout time.Duration) (string, error)\n}\n","sourceCodeStart":298,"sourceCodeEnd":324,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/cloud-web/gateway.go#L298-L324","documentation":"A card preview was requested through the gateway transport and the transport waited for the cloud-web server to deliver an async 'preview_ack' event (routed via the webhook listener), but no ack arrived before the timeout elapsed. The pending ref_id is cleaned up and a handle is not produced, so the preview cannot be finalized.","triggerScenarios":"waitPreviewAck's select times out: the server never sent preview_ack, it was delayed beyond the timeout, the ack was dropped (webhook unreachable, auth failing so webhookHandler returns 401, or the gateway listener from error 1000 never came up), or the ack's ref_id did not match.","commonSituations":"Inbound webhook URL not reachable from the server (firewall/NAT, wrong public_url) so acks never arrive; Authorization token mismatch causing 401 on every webhook POST; preview generation genuinely slow server-side; timeout configured too aggressively.","solutions":["Check gateway logs for incoming webhook POSTs; 401s mean fix the shared token so acks authenticate.","Verify public_url is externally reachable from the cloud-web server (curl the webhook URL from the server host).","Increase the preview timeout so slow server-side preview generation completes.","If the gateway listener failed to start (error 'gateway listen'), fix that first — acks are delivered through it."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// before requesting a preview, confirm the webhook is reachable from the server\n// (run on the cloud-web server host):\n// curl -s -o /dev/null -w '%{http_code}' -X POST -H 'Authorization: Bearer <token>' https://cc-connect-host:8099/cloud-web/webhook\n// expect 200 (or 400 for empty body), not 000/401","typeGuard":null,"tryCatchPattern":"handle, err := platform.RequestPreview(ctx, refID)\nif err != nil && strings.Contains(err.Error(), \"preview_ack timeout\") {\n    slog.Warn(\"preview ack timed out; retrying once with longer deadline\", \"ref\", refID)\n    handle, err = platform.RequestPreview(ctxWithLongerTimeout, refID)\n}","preventionTips":["Make public_url externally resolvable and reachable from the cloud-web server","Keep the shared token in sync so webhook POSTs are not 401-rejected","Set the preview timeout comfortably above server-side preview latency","Confirm the gateway listener started successfully in logs before issuing previews"],"tags":["timeout","preview","async","cloud-web"],"backgroundTag":"request-timeout","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}