jackwener/OpenCLI · error · CommandExecutionError

Failed to read Upwork search state: ${e?.message ?? e}

Error message

Failed to read Upwork search state: ${e?.message ?? e}

What it means

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.

Source

Thrown at clis/upwork/search.js:84

                    await new Promise(r => setTimeout(r, 500));
                    ready = haveState();
                }
                const onLogin = /\\/(ab\\/account-security\\/login|nx\\/login)/.test(location.pathname);
                const challenge = (document.title || '').toLowerCase().includes('just a moment') || !!document.querySelector('[id^="cf-"]');
                const state = window.__NUXT__ && window.__NUXT__.state && window.__NUXT__.state.jobsSearch;
                return {
                    ready,
                    onLogin,
                    challenge,
                    jobsPresent: !!(state && Object.prototype.hasOwnProperty.call(state, 'jobs')),
                    jobs: state ? state.jobs : undefined,
                    paging: state && state.paging ? state.paging : null,
                    status: state ? state.status : null,
                };
            })()`));
        }
        catch (e) {
            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.');
        }

        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 (!payload?.ready) {
            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.');
        }
        if (!isPlainObject(payload)) {
            throw new CommandExecutionError('Upwork search returned an unexpected Browser Bridge payload shape');
        }
        if (!payload.jobsPresent || !Array.isArray(payload.jobs)) {
            throw new CommandExecutionError('Upwork search state had an unexpected jobs shape; expected window.__NUXT__.state.jobsSearch.jobs to be an array.');
        }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Open https://www.upwork.com in the connected browser, wait for it to fully load, then retry the command.
  2. Check the wrapped cause message (e?.message) to see whether the tab closed, navigated, or the bridge disconnected, and fix that underlying issue.
  3. Retry after confirming the active bridge tab is on an Upwork jobs search URL.
  4. If __NUXT__ is consistently absent, Upwork may have changed its SSR state shape - update the CLI's state-reading script.

Example fix

// before
const state = await bridge.eval(() => window.__NUXT__.state) // throws TypeError when __NUXT__ is undefined
// after
const state = await bridge.eval(() => (window.__NUXT__ && window.__NUXT__.state) ? window.__NUXT__.state : null); // then throw AuthRequiredError/CommandExecutionError explicitly on null
Defensive patterns

Strategy: retry

Validate before calling

// before calling, confirm the bridge tab is on Upwork and loaded
if (!browserTab.url().includes('upwork.com')) throw new Error('Connect the bridge to an upwork.com tab');
if (document.readyState !== 'complete') await waitUntilLoaded();

Type guard

function hasNuxtState(win) {
  return typeof win === 'object' && win !== null &&
    typeof win.__NUXT__ === 'object' && win.__NUXT__ !== null &&
    typeof win.__NUXT__.state === 'object';
}

Try / catch

try {
  const rows = await cli.search(query);
} catch (e) {
  if (String(e.message).startsWith('Failed to read Upwork search state')) {
    await reloadUpworkTab(); // reopen/load upwork.com, then retry once
    rows = await cli.search(query);
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/814b7123c0a2eac2. Report an issue: GitHub.