Bug
With OpenCLI v1.7.18 and Browser Bridge extension v1.0.12, twitter search fails consistently:
opencli twitter search "from:@aleabitoreddit" --limit 3 -f yaml
Observed output:
ok: false
error:
code: COMMAND_EXEC
message: 'SPA navigation to /search failed. Final path: [object Object]. Twitter may have changed its routing.'
exitCode: 1
opencli doctor is OK in the same environment:
opencli v1.7.18 doctor (node v25.9.0)
[OK] Daemon: running on port 19825 (v1.7.18)
[OK] Extension: connected (v1.0.12)
[OK] Connectivity: connected in 0.1s
Root cause
clis/twitter/search.js currently does scalar page.evaluate reads for the SPA path:
lastPath = String(await page.evaluate('() => window.location.pathname') || '');
Under the current daemon/extension protocol, exec scalar results come back with a session envelope. A direct daemon probe shows this shape:
{
"ok": true,
"data": {
"session": "site:twitter",
"data": "/search"
},
"page": "..."
}
So String(await page.evaluate(...)) becomes [object Object], causing the reported failure even when the browser did navigate to /search.
There is a related issue after navigation: BasePage.getInterceptedRequests() only accepts a bare array:
const result = await this.evaluate(generateReadInterceptedJs('__opencli_xhr'));
return Array.isArray(result) ? result : [];
But interceptor reads may also come back as an envelope:
{ "session": "site:twitter", "data": [ ...captured requests... ] }
So twitter search can lose the captured SearchTimeline requests unless this shape is handled.
Regression window / related PRs
Between v1.7.15 and v1.7.18, clis/twitter/search.js mainly changed from one-shot to a persistent site session:
browser: true,
+siteSession: 'persistent',
Relevant commits/PRs:
PR #1451 does not appear to directly touch twitter/search.js.
Local workaround verified
A local workaround that follows the current envelope shape fixed the issue:
- In
twitter/search.js, make pathname reads return an object and read value.path / value.data safely instead of coercing the whole result with String(...).
- In
BasePage.getInterceptedRequests(), accept { data: [...] } envelopes.
Verification after the local workaround:
opencli twitter search "from:@aleabitoreddit" --limit 3 -f yaml
# returns 3 tweets, exit 0
opencli twitter search "from:@aleabitoreddit" --limit 1 --product live -f yaml
# returns 1 tweet, exit 0
opencli twitter timeline --limit 1 -f yaml
# still works, exit 0
I did not find an existing helper like page.evaluateScalar() / page.evaluateUnwrap() in v1.7.18. If the intended protocol is for Page.evaluate() to return the raw browser result, the unwrap should probably live in the browser/page layer. If the intended protocol is for adapters to handle the session envelope explicitly, twitter/search.js and getInterceptedRequests() need to be updated to follow that convention.
Bug
With OpenCLI v1.7.18 and Browser Bridge extension v1.0.12,
twitter searchfails consistently:opencli twitter search "from:@aleabitoreddit" --limit 3 -f yamlObserved output:
opencli doctoris OK in the same environment:Root cause
clis/twitter/search.jscurrently does scalarpage.evaluatereads for the SPA path:Under the current daemon/extension protocol,
execscalar results come back with a session envelope. A direct daemon probe shows this shape:{ "ok": true, "data": { "session": "site:twitter", "data": "/search" }, "page": "..." }So
String(await page.evaluate(...))becomes[object Object], causing the reported failure even when the browser did navigate to/search.There is a related issue after navigation:
BasePage.getInterceptedRequests()only accepts a bare array:But interceptor reads may also come back as an envelope:
{ "session": "site:twitter", "data": [ ...captured requests... ] }So
twitter searchcan lose the capturedSearchTimelinerequests unless this shape is handled.Regression window / related PRs
Between v1.7.15 and v1.7.18,
clis/twitter/search.jsmainly changed from one-shot to a persistent site session:browser: true, +siteSession: 'persistent',Relevant commits/PRs:
833c1c87: addedbrowserSession: { reuse: 'site' }to Twitter read-only adapters, includingtwitter/search.js.9c06e84c: workspace -> explicit sessions / surface refactor.467fdd0b: renamed browser reuse tositeSession: 'persistent'.PR #1451 does not appear to directly touch
twitter/search.js.Local workaround verified
A local workaround that follows the current envelope shape fixed the issue:
twitter/search.js, make pathname reads return an object and readvalue.path/value.datasafely instead of coercing the whole result withString(...).BasePage.getInterceptedRequests(), accept{ data: [...] }envelopes.Verification after the local workaround:
I did not find an existing helper like
page.evaluateScalar()/page.evaluateUnwrap()in v1.7.18. If the intended protocol is forPage.evaluate()to return the raw browser result, the unwrap should probably live in the browser/page layer. If the intended protocol is for adapters to handle the session envelope explicitly,twitter/search.jsandgetInterceptedRequests()need to be updated to follow that convention.