jackwener/OpenCLI · error · CommandExecutionError
Upwork feed state had an unexpected jobs shape; expected win
Error message
Upwork feed state had an unexpected jobs shape; expected window.__NUXT__.state.${stateKey}.jobs to be an array. What it means
Once ready, the CLI requires window.__NUXT__.state.<feedKey>.jobs to be an actual array (jobsPresent checks the key exists; Array.isArray validates its type). This CommandExecutionError is thrown when the jobs key is missing or is not an array, meaning Upwork's feed state schema no longer matches what the CLI expects — an upstream shape change rather than an empty feed.
Source
Thrown at clis/upwork/feed.js:95
}
catch (e) {
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.');
}
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 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.');
}
if (!isPlainObject(payload)) {
throw new CommandExecutionError('Upwork feed returned an unexpected Browser Bridge payload shape');
}
if (!payload.jobsPresent || !Array.isArray(payload.jobs)) {
throw new CommandExecutionError(`Upwork feed state had an unexpected jobs shape; expected window.__NUXT__.state.${stateKey}.jobs to be an array.`);
}
const jobs = payload.jobs;
if (jobs.length === 0) {
throw new EmptyResultError(`upwork feed ${tab}`, `Upwork ${tab} feed is empty for the current account`);
}
const rows = jobsToListRows(jobs, { limit });
if (rows.length === 0) {
throw new CommandExecutionError('Upwork feed results did not include any job with a valid ciphertext id; cannot produce round-trippable detail rows.');
}
return rows;
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Inspect window.__NUXT__.state.feedBestMatch in DevTools on the open feed page to see the new shape; if jobs moved or was renamed, update the CLI or pin to a compatible Upwork experience.
- Retry — A/B bucketing is usually sticky per session, so a fresh profile may get the old shape.
- Update @jackwener/opencli to the latest version which may track the new Upwork state schema.
- Use the other tab (`upwork feed most-recent`) whose state key may still match, as a workaround.
Example fix
// before
if (!payload.jobsPresent || !Array.isArray(payload.jobs)) throw new CommandExecutionError(...);
// after — defensive extraction against a redesigned state
const state = payload.state || {};
const jobs = Array.isArray(state.jobs) ? state.jobs
: Array.isArray(state.feed?.jobs) ? state.feed.jobs
: null;
if (!jobs) throw new CommandExecutionError(`Unexpected jobs shape; got keys: ${Object.keys(state)}`); Defensive patterns
Strategy: validation
Validate before calling
// pre-flight: confirm the state key still exists in the live page
const hasJobsArray = await bridge.evaluate("Array.isArray(window.__NUXT__?.state?.feedBestMatch?.jobs)");
if (!hasJobsArray) console.warn('Upwork state schema changed; update the CLI.'); Type guard
function hasJobsArray(payload) {
return payload != null
&& Array.isArray(payload.jobs);
} Try / catch
try {
const jobs = await upwork.feed();
} catch (e) {
if (/unexpected jobs shape/.test(e.message)) {
// upstream schema change: pin an older Upwork experience (fresh profile) or upgrade the CLI
return upgradeCliOrInspectState(e);
}
throw e;
} Prevention
- Update the CLI promptly when Upwork ships redesigns; this error is a drift signal.
- Inspect __NUXT__.state in DevTools when it fires to capture the new shape.
- Pin/track the opencli package version in CI so behavior is reproducible.
When it happens
Trigger: Running `upwork feed` when state.feedBestMatch (or feedMostRecent) exists but has no jobs property, or jobs is an object/null/string instead of an array — after an Upwork frontend update that restructures the Nuxt state, or when the state node belongs to a different feed type than requested.
Common situations: Upwork A/B tests or redesigns moving jobs into a nested object; requesting a tab whose state key Upwork renamed; a locale/experiment serving a different state shape; stale CLI version against a newer Upwork build.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Upwork job-detail store had an unexpected job shape; expecte
- Failed to read Upwork feed state: ${e?.message ?? e}
- Upwork feed state (window.__NUXT__.state.${stateKey}) was no
- Upwork feed results did not include any job with a valid cip
- Mercury returned malformed click result
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/daf1eb598a7e7481.
Report an issue: GitHub.