jackwener/OpenCLI · error · CommandExecutionError

Upwork feed results did not include any job with a valid cip

Error message

Upwork feed results did not include any job with a valid ciphertext id; cannot produce round-trippable detail rows.

What it means

The feed maps raw job entries to list rows via jobsToListRows, keeping only jobs that carry a valid ciphertext id so each row can be opened again with `upwork detail`. If the filtered result is empty even though the raw jobs array was non-empty, this CommandExecutionError is thrown: none of the feed entries had a usable ciphertext, so the CLI refuses to emit rows that cannot round-trip to detail.

Source

Thrown at clis/upwork/feed.js:105

        }
        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

  1. Retry after a short wait — if ids hydrate late, a re-run may pick up fully populated entries.
  2. Inspect one entry of window.__NUXT__.state.feedBestMatch.jobs in DevTools to find where the ciphertext now lives, and update jobsToListRows (or the CLI package) accordingly.
  3. Update @jackwener/opencli to the latest version that tracks the current Upwork feed schema.
  4. As a workaround, fetch jobs via `upwork search`, whose rows may still carry valid ciphertext ids.

Example fix

// before
const rows = jobsToListRows(jobs, { limit });
// after — diagnose which field now holds the id
const sample = jobs[0] || {};
const idKey = Object.keys(sample).find(k => /^~0[12]/.test(String(sample[k] || '')));
if (!idKey) throw new CommandExecutionError('No ciphertext-like field in feed job: ' + JSON.stringify(Object.keys(sample)));
const rows = jobsToListRows(jobs, { limit, idKey });
Defensive patterns

Strategy: validation

Validate before calling

// verify ids exist in feed data before relying on round-trip
const res = await upwork.feed();
const allHaveIds = res.rows.every(r => /^~0[12]/.test(r.id));
if (!allHaveIds) console.warn('Feed rows missing ciphertext ids; detail round-trip will fail.');

Type guard

function hasCiphertextId(job) {
  return job != null
    && typeof job.ciphertext === 'string'
    && /^~0[12]/.test(job.ciphertext);
}

Try / catch

try {
  const rows = await upwork.feed();
} catch (e) {
  if (/valid ciphertext id/.test(e.message)) {
    // schema drift: inspect the raw jobs array for the new id field, or use `upwork search` rows
    return fallbackToSearchRows();
  }
  throw e;
}

Prevention

When it happens

Trigger: Running `upwork feed` when every job object in the feed state lacks the expected ciphertext field (or it's empty after trim/normalization) — e.g. an Upwork schema change renaming the id field, job entries being placeholder/promo cards without ids, or jobsToListRows' normalization no longer matching the id key Upwork uses.

Common situations: Upwork redesign changing the job id property name in __NUXT__ state; feed entries injected by experiments or ads that have no ciphertext; a stale CLI whose jobsToListRows expects an older field name; partially hydrated state where job ids load late.

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


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