jackwener/OpenCLI · error · CommandExecutionError
Upwork detail returned an unexpected Browser Bridge payload
Error message
Upwork detail returned an unexpected Browser Bridge payload shape
What it means
After the login/challenge checks, the command validates that the Browser Bridge payload is a plain object via isPlainObject. If the evaluate returned null, an array, a string, or otherwise non-object data, it throws CommandExecutionError reporting the unexpected payload shape, preventing downstream property access on garbage.
Source
Thrown at clis/upwork/detail.js:89
onLogin,
challenge,
job: s.job ? JSON.parse(JSON.stringify(s.job)) : null,
buyer: s.buyer ? JSON.parse(JSON.stringify(s.buyer)) : null,
};
})()`));
}
catch (e) {
throw new CommandExecutionError(`Failed to read Upwork job-detail store: ${e?.message ?? e}`, 'The Vuex store was not reachable; try again after opening Upwork in the connected browser.');
}
if (payload?.onLogin) {
throw new AuthRequiredError('upwork.com', 'Upwork redirected to login. Open https://www.upwork.com in the connected browser and sign in, then retry.');
}
if (payload?.challenge) {
throw new CommandExecutionError('Upwork served a Cloudflare challenge page', 'Open https://www.upwork.com in the connected browser and clear the challenge, then retry.');
}
if (!isPlainObject(payload)) {
throw new CommandExecutionError('Upwork detail returned an unexpected Browser Bridge payload shape');
}
if (!payload?.ready || !payload.job) {
throw new EmptyResultError('upwork detail', `No Upwork job posting found for id "${id}" (may be closed, expired, or private)`);
}
if (!isPlainObject(payload.job)) {
throw new CommandExecutionError('Upwork job-detail store had an unexpected job shape; expected an object.');
}
const job = payload.job;
const returnedCiphertext = String(job?.ciphertext ?? '').trim();
if (returnedCiphertext && returnedCiphertext !== id) {
throw new CommandExecutionError(`Upwork job-detail store returned ciphertext "${returnedCiphertext}" while reading "${id}".`);
}
const buyer = payload.buyer || {};
const stats = buyer?.stats || {};
const location = buyer?.location || {};
const category = job?.category?.name || '';
const skills = formatSkills(job);View on GitHub (pinned to 49907e53dc)
Solutions
- Retry with the Upwork job page fully loaded and idle (no pending navigation).
- Update the library — mismatched Browser Bridge/injection versions are a frequent cause of shape drift.
- Open the job page manually in the connected browser to confirm it renders normally before running the command.
- If reproducible on a healthy page, report/inspect: Upwork may have changed its store structure and the extractor needs updating.
- Restart the browser bridge connection to rule out stale sessions returning empty results.
Defensive patterns
Strategy: type-guard
Validate before calling
await page.goto(jobUrl, { waitUntil: 'networkidle' });
if (!page.url().includes('upwork.com')) throw new Error('Navigation left Upwork; payload shape cannot be trusted'); Type guard
function isPlainObject(v) {
if (v === null || typeof v !== 'object') return false;
const proto = Object.getPrototypeOf(v);
return proto === Object.prototype || proto === null;
} Try / catch
try {
const detail = await fetchUpworkJobDetail(id);
} catch (e) {
if (e instanceof CommandExecutionError && /unexpected Browser Bridge payload shape/.test(e.message)) {
await page.waitForNetworkIdle();
return fetchUpworkJobDetail(id); // retry once after the page settles
}
throw e;
} Prevention
- Run fetches only when the page is idle — mid-navigation evaluate often returns null/undefined.
- Keep CLI and browser-bridge/injection versions in sync; shape mismatches cause this error.
- Pre-validate results with an isPlainObject guard before accessing properties.
- If persistent on a healthy page, suspect an Upwork site change and update the extractor.
When it happens
Trigger: The in-page extraction IIFE returns something other than a plain object — evaluate cancelled mid-navigation, script exception produced undefined, a Browser Bridge serialization mismatch, or page context returned a primitive.
Common situations: Page navigated/reloaded during evaluate so the result is undefined/null; a version mismatch between CLI extraction script and the injected bridge; Upwork page erroring before the store reader builds its result object; extensions interfering with page scripts.
Related errors
- Upwork feed returned an unexpected Browser Bridge payload sh
- Upwork search returned an unexpected Browser Bridge payload
- Chess.com API returned an unexpected payload shape for ${url
- ${label}
- Instagram profile returned malformed user payload for: ${use
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/adf447e6c88bea7e.
Report an issue: GitHub.