{"record":{"id":"814b7123c0a2eac2","repo":"jackwener/OpenCLI","slug":"failed-to-read-upwork-search-state-e-message","errorCode":null,"errorMessage":"Failed to read Upwork search state: ${e?.message ?? e}","messagePattern":"Failed to read Upwork search state: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/upwork/search.js","lineNumber":84,"sourceCode":"                    await new Promise(r => setTimeout(r, 500));\n                    ready = haveState();\n                }\n                const onLogin = /\\\\/(ab\\\\/account-security\\\\/login|nx\\\\/login)/.test(location.pathname);\n                const challenge = (document.title || '').toLowerCase().includes('just a moment') || !!document.querySelector('[id^=\"cf-\"]');\n                const state = window.__NUXT__ && window.__NUXT__.state && window.__NUXT__.state.jobsSearch;\n                return {\n                    ready,\n                    onLogin,\n                    challenge,\n                    jobsPresent: !!(state && Object.prototype.hasOwnProperty.call(state, 'jobs')),\n                    jobs: state ? state.jobs : undefined,\n                    paging: state && state.paging ? state.paging : null,\n                    status: state ? state.status : null,\n                };\n            })()`));\n        }\n        catch (e) {\n            throw new CommandExecutionError(`Failed to read Upwork search 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 search state (window.__NUXT__.state.jobsSearch) 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 search returned an unexpected Browser Bridge payload shape');\n        }\n        if (!payload.jobsPresent || !Array.isArray(payload.jobs)) {\n            throw new CommandExecutionError('Upwork search state had an unexpected jobs shape; expected window.__NUXT__.state.jobsSearch.jobs to be an array.');\n        }\n","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/upwork/search.js#L66-L102","documentation":"The CLI tried to read the Upwork search state (window.__NUXT__) through the Browser Bridge and the underlying evaluation threw, so it wraps the cause in a CommandExecutionError. This means the page context was reachable enough to attempt injection but the Nuxt state global could not be read. The library throws it because without SSR state it cannot build search results at all.","triggerScenarios":"Calling the upwork search command when the connected browser tab failed to expose window.__NUXT__ during evaluation - e.g. the tab navigated mid-read, the evaluation itself raised, or the page is a hard client-rendered shell with no Nuxt payload.","commonSituations":"Upwork is still loading or just navigated; a slow/hung tab where the bridge read times out or errors; an Upwork A/B rollout changed the page so __NUXT__ no longer exists; reading from a non-Upwork tab; the browser was closed between session open and the read.","solutions":["Open https://www.upwork.com in the connected browser, wait for it to fully load, then retry the command.","Check the wrapped cause message (e?.message) to see whether the tab closed, navigated, or the bridge disconnected, and fix that underlying issue.","Retry after confirming the active bridge tab is on an Upwork jobs search URL.","If __NUXT__ is consistently absent, Upwork may have changed its SSR state shape - update the CLI's state-reading script."],"exampleFix":"// before\nconst state = await bridge.eval(() => window.__NUXT__.state) // throws TypeError when __NUXT__ is undefined\n// after\nconst state = await bridge.eval(() => (window.__NUXT__ && window.__NUXT__.state) ? window.__NUXT__.state : null); // then throw AuthRequiredError/CommandExecutionError explicitly on null","handlingStrategy":"retry","validationCode":"// before calling, confirm the bridge tab is on Upwork and loaded\nif (!browserTab.url().includes('upwork.com')) throw new Error('Connect the bridge to an upwork.com tab');\nif (document.readyState !== 'complete') await waitUntilLoaded();","typeGuard":"function hasNuxtState(win) {\n  return typeof win === 'object' && win !== null &&\n    typeof win.__NUXT__ === 'object' && win.__NUXT__ !== null &&\n    typeof win.__NUXT__.state === 'object';\n}","tryCatchPattern":"try {\n  const rows = await cli.search(query);\n} catch (e) {\n  if (String(e.message).startsWith('Failed to read Upwork search state')) {\n    await reloadUpworkTab(); // reopen/load upwork.com, then retry once\n    rows = await cli.search(query);\n  } else throw e;\n}","preventionTips":["Always open and fully load upwork.com in the connected browser before running search commands.","Retry transient state reads; single-shot reads are fragile against SPA navigation.","Pin/watch for Upwork frontend changes that remove window.__NUXT__.","Keep the browser tab in the foreground and avoid navigating it during a command."],"tags":["browser-automation","scraping","upwork","state-read"],"backgroundTag":"browser-bridge-state-unreachable","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}