{"record":{"id":"5c06f3d6fd8ff0e9","repo":"tinyhumansai/openhuman","slug":"composio-polling-connections-failed","errorCode":null,"errorMessage":"[composio] polling connections failed:","messagePattern":"\\[composio\\] polling connections failed:","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/src/lib/composio/hooks.ts","lineNumber":242,"sourceCode":"  }, [fetchEnabled, resolveFetchEnabled]);\n\n  // Initial fetch + polling.\n  useEffect(() => {\n    void refresh();\n    if (pollIntervalMs <= 0 || fetchEnabled !== true) return;\n    const id = window.setInterval(() => {\n      const generation = configGenerationRef.current;\n      void listConnections({ timeoutMs: COMPOSIO_FETCH_TIMEOUT_MS })\n        .then(resp => {\n          if (!mountedRef.current || generation !== configGenerationRef.current) return;\n          const freshConnections = resp.connections ?? [];\n          setConnections(freshConnections);\n          // Keep the durable cache current with each poll so a restart paints\n          // the freshest activation state (merge preserves toolkit/catalog).\n          writeConnectionCache({ connections: freshConnections });\n        })\n        .catch(err => {\n          console.warn(\n            '[composio] polling connections failed:',\n            err instanceof Error ? err.message : String(err)\n          );\n        });\n    }, pollIntervalMs);\n    return () => window.clearInterval(id);\n  }, [refresh, pollIntervalMs, fetchEnabled]);\n\n  // [composio-cache] Listen for a window-level \"config changed\" event\n  // emitted by ComposioPanel when the user flips backend ↔ direct or\n  // stores/clears the BYO API key. Without this, the integrations panel\n  // keeps showing the previous tenant's connections for up to one poll\n  // interval (5s) — visible enough to look like a bug (#1710). On the\n  // event we trigger a full refresh which re-fetches toolkits +\n  // connections against the new client. We also rely on the Rust-side\n  // ComposioConfigChanged bus event to invalidate the core-side cache;\n  // the window event is purely an in-renderer signal.\n  useEffect(() => {","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/tinyhumansai/openhuman/blob/749120085864ce16e0f273c7b86fac7740b39c5b/app/src/lib/composio/hooks.ts#L224-L260","documentation":"Failure of the periodic Composio connections poll: listConnections({timeoutMs}) inside window.setInterval rejected (network/timeout/backend error). The generation guard means stale responses are already dropped; the catch only warns, connections keep their last-known value and the next interval tick retries automatically.","triggerScenarios":"Thrown at app/src/lib/composio/hooks.ts:242 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Rely on the next poll tick — retries are built into the interval","Inspect the underlying error kind: timeout vs auth determines whether polling can ever succeed","Back off or stop polling after consecutive failures to avoid log spam"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"749120085864ce16e0f273c7b86fac7740b39c5b","analyzedAt":"2026-08-17T21:21:45.363Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}