{"record":{"id":"4981620801ca06d3","repo":"jackwener/OpenCLI","slug":"twitter-followers-interceptor-returned-malformed-r","errorCode":null,"errorMessage":"Twitter followers interceptor returned malformed responses","messagePattern":"Twitter followers interceptor returned malformed responses","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/twitter/followers.js","lineNumber":158,"sourceCode":"        }\n        catch {\n            throw new TimeoutError('twitter followers API capture', CAPTURE_TIMEOUT_SECONDS, 'No Followers response was observed after opening the followers list.');\n        }\n        const currentPath = unwrapBrowserResult(await page.evaluate('() => window.location.pathname'));\n        if (typeof currentPath !== 'string' || !currentPath.toLowerCase().endsWith('/followers')) {\n            throw new CommandExecutionError('SPA navigation to Twitter followers failed');\n        }\n\n        const allFollowers = [];\n        const seen = new Set();\n        let cursor = null;\n        let lastRawResponse = null;\n        let pages = 0;\n\n        const consumeCaptured = async () => {\n            const requests = await page.getInterceptedRequests();\n            if (!Array.isArray(requests)) {\n                throw new CommandExecutionError('Twitter followers interceptor returned malformed responses');\n            }\n            for (const request of requests) {\n                const { data, users, nextCursor } = parseFollowers(request);\n                const graphqlError = twitterGraphqlError(data);\n                if (graphqlError)\n                    throw new CommandExecutionError(graphqlError);\n                lastRawResponse = data;\n                for (const user of users) {\n                    if (!seen.has(user.screen_name)) {\n                        seen.add(user.screen_name);\n                        allFollowers.push(user);\n                    }\n                }\n                cursor = nextCursor;\n            }\n        };\n\n        await consumeCaptured();","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/followers.js#L140-L176","documentation":"Inside consumeCaptured, the result of page.getInterceptedRequests() must be an array of captured requests. If the browser bridge returns anything else (null, undefined, an object), the interceptor contract is broken and the command cannot parse followers, so it throws CommandExecutionError. This indicates a bridge/interceptor plumbing problem, not a Twitter-side issue.","triggerScenarios":"page.getInterceptedRequests() returns a non-Array — the interceptor was never installed, the browser bridge/session changed shape (e.g. unwrapping mismatch in unwrapBrowserResult), or a library version mismatch between the page bridge and the CLI.","commonSituations":"Upgrading one half of the opencli bridge but not the other; running against a custom/unofficial browser backend whose getInterceptedRequests returns an object wrapper; interceptor installation failed silently earlier.","solutions":["Ensure the opencli bridge and CLI versions match (upgrade both together)","Verify installInterceptor('/Followers?') succeeded before consuming","Unwrap the bridge result if getInterceptedRequests returns { session, data } style wrappers","Report the raw return value to the library maintainers if it persists"],"exampleFix":"// before\nconst requests = await page.getInterceptedRequests();\nif (!Array.isArray(requests)) throw ...\n// after (unwrap bridge envelope first)\nconst raw = unwrapBrowserResult(await page.getInterceptedRequests());\nconst requests = Array.isArray(raw) ? raw : (Array.isArray(raw?.data) ? raw.data : []);","handlingStrategy":"type-guard","validationCode":"null","typeGuard":"function isCapturedRequests(v) {\n  return Array.isArray(v);\n}\n// usage: if (!isCapturedRequests(await page.getInterceptedRequests())) fail fast;","tryCatchPattern":"try {\n  const rows = await opencli.twitter.followers(user, { limit });\n} catch (err) {\n  if (err.message.includes('interceptor returned malformed responses')) {\n    // bridge/interceptor contract issue: reinstall interceptor, align versions, or retry\n    return opencli.twitter.followers(user, { limit });\n  } else throw err;\n}","preventionTips":["Keep the opencli CLI and browser bridge on matching versions","Confirm installInterceptor succeeds before calling getInterceptedRequests","Log the raw return value when debugging bridge mismatches","Pin library versions in CI to avoid half-upgraded bridge states"],"tags":["interception","twitter","bridge","contract-violation"],"backgroundTag":"unexpected-response-shape","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}