{"record":{"id":"8617e3462b1a3609","repo":"jackwener/OpenCLI","slug":"upwork-feed-returned-an-unexpected-browser-bridge","errorCode":null,"errorMessage":"Upwork feed returned an unexpected Browser Bridge payload shape","messagePattern":"Upwork feed returned an unexpected Browser Bridge payload shape","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/upwork/feed.js","lineNumber":92,"sourceCode":"                    paging: state && state.paging ? state.paging : null,\n                };\n            })()`));\n        }\n        catch (e) {\n            throw new CommandExecutionError(`Failed to read Upwork feed state: ${e?.message ?? e}`, 'The Nuxt state global was not reachable; try again after opening Upwork in the connected browser.');\n        }\n\n        if (payload?.onLogin) {\n            throw new AuthRequiredError('upwork.com', 'Upwork redirected to login. Open https://www.upwork.com in the connected browser and sign in, then retry.');\n        }\n        if (payload?.challenge) {\n            throw new CommandExecutionError('Upwork served a Cloudflare challenge page', 'Open https://www.upwork.com in the connected browser and clear the challenge, then retry.');\n        }\n        if (!payload?.ready) {\n            throw new CommandExecutionError(`Upwork feed state (window.__NUXT__.state.${stateKey}) was not present within 15s`, 'The page may not have finished hydrating, or the SSR state shape may have changed.');\n        }\n        if (!isPlainObject(payload)) {\n            throw new CommandExecutionError('Upwork feed returned an unexpected Browser Bridge payload shape');\n        }\n        if (!payload.jobsPresent || !Array.isArray(payload.jobs)) {\n            throw new CommandExecutionError(`Upwork feed state had an unexpected jobs shape; expected window.__NUXT__.state.${stateKey}.jobs to be an array.`);\n        }\n\n        const jobs = payload.jobs;\n        if (jobs.length === 0) {\n            throw new EmptyResultError(`upwork feed ${tab}`, `Upwork ${tab} feed is empty for the current account`);\n        }\n\n        const rows = jobsToListRows(jobs, { limit });\n        if (rows.length === 0) {\n            throw new CommandExecutionError('Upwork feed results did not include any job with a valid ciphertext id; cannot produce round-trippable detail rows.');\n        }\n        return rows;\n    },\n});\n","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/upwork/feed.js#L74-L110","documentation":"The feed command validates that the value returned by the browser bridge is a plain object before inspecting its fields. This CommandExecutionError is thrown when unwrapBrowserResult yields something other than a plain object (null, undefined, array, or primitive), meaning the bridge layer between the page and the CLI mangled or dropped the payload. It is a defensive shape check on the CLI's own plumbing rather than the Upwork page.","triggerScenarios":"page.evaluate's promise resolves but unwrapBrowserResult returns a non-object — e.g. the browser bridge failed to serialize the async IIFE result, returned an error-wrapped value, or the connected-browser transport delivered null/undefined; also hit if the evaluate expression itself was corrupted.","commonSituations":"Browser bridge/transport version mismatch between CLI and the connected browser helper; the page navigating mid-evaluation so the result is lost; custom bridge wrappers returning {error: ...} objects that unwrap to non-objects; running with an outdated opencli package.","solutions":["Retry the command — mid-navigation races commonly cause a lost payload once and not again.","Update @jackwener/opencli (CLI and any browser-bridge helper) to matching, current versions.","Ensure the connected browser stays on the Upwork tab for the duration of the command (don't navigate away).","If reproducible, log the raw evaluate result before unwrapBrowserResult and report a bridge bug."],"exampleFix":"// before\nconst payload = unwrapBrowserResult(await page.evaluate(expr)); // assumed object\n// after\nconst raw = await page.evaluate(expr);\nconst payload = unwrapBrowserResult(raw);\nif (!payload || typeof payload !== 'object' || Array.isArray(payload)) {\n  throw new CommandExecutionError('bridge returned non-object payload: ' + JSON.stringify(raw));\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function isPlainObject(v) {\n  return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n// use after any bridge call: if (!isPlainObject(payload)) handleBridgeFault();","tryCatchPattern":"try {\n  const jobs = await upwork.feed();\n} catch (e) {\n  if (/unexpected Browser Bridge payload shape/.test(e.message)) {\n    // transport glitch: one retry, then report bridge/CLI version mismatch\n    return attempt < 2 ? feedWithRetry(attempt + 1) : reportBridgeBug(e);\n  }\n  throw e;\n}","preventionTips":["Keep the CLI and the connected-browser bridge helper on matching, current versions.","Don't navigate the browser away from Upwork while a command is in flight.","Log the raw bridge result when this fires to distinguish transport bugs from page changes."],"tags":["upwork","browser-bridge","payload-shape","serialization","command-execution-error"],"backgroundTag":"unexpected-payload-shape","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}