jackwener/OpenCLI · error · AuthRequiredError

Upwork redirected to login. Open https://www.upwork.com in t

Error message

Upwork redirected to login. Open https://www.upwork.com in the connected browser and sign in, then retry.

What it means

After reading the Vuex store, the payload's onLogin flag indicates Upwork served a login redirect instead of job content. The command throws AuthRequiredError instructing the user to sign in via the connected browser, since authenticated job data can't be fetched anonymously.

Source

Thrown at clis/upwork/detail.js:83

                if (!ready) {
                    return { ready, onLogin, challenge, job: null, buyer: null };
                }
                const s = window.$nuxt.$store.state.jobDetails;
                return {
                    ready,
                    onLogin,
                    challenge,
                    job: s.job ? JSON.parse(JSON.stringify(s.job)) : null,
                    buyer: s.buyer ? JSON.parse(JSON.stringify(s.buyer)) : null,
                };
            })()`));
        }
        catch (e) {
            throw new CommandExecutionError(`Failed to read Upwork job-detail store: ${e?.message ?? e}`, 'The Vuex store 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 (!isPlainObject(payload)) {
            throw new CommandExecutionError('Upwork detail returned an unexpected Browser Bridge payload shape');
        }
        if (!payload?.ready || !payload.job) {
            throw new EmptyResultError('upwork detail', `No Upwork job posting found for id "${id}" (may be closed, expired, or private)`);
        }
        if (!isPlainObject(payload.job)) {
            throw new CommandExecutionError('Upwork job-detail store had an unexpected job shape; expected an object.');
        }

        const job = payload.job;
        const returnedCiphertext = String(job?.ciphertext ?? '').trim();
        if (returnedCiphertext && returnedCiphertext !== id) {
            throw new CommandExecutionError(`Upwork job-detail store returned ciphertext "${returnedCiphertext}" while reading "${id}".`);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Open https://www.upwork.com in the connected browser and sign in, then re-run the detail command.
  2. Use the library's upwork login flow to establish a fresh session.
  3. Verify session cookies exist (master_access_token or XSRF-TOKEN + user_uid) before fetching.
  4. If you are logged in but still redirected, log out and back in to refresh stale tokens.
Defensive patterns

Strategy: validation

Validate before calling

const cookies = await page.cookies('https://www.upwork.com');
if (!hasUpworkSessionCookie(cookies)) {
  throw new Error('Authenticate first: open https://www.upwork.com and sign in');
}

Try / catch

try {
  const detail = await fetchUpworkJobDetail(id);
} catch (e) {
  if (e instanceof AuthRequiredError) {
    await runInteractiveLogin(page); // or prompt user to sign in manually
    return fetchUpworkJobDetail(id);
  }
  throw e;
}

Prevention

When it happens

Trigger: Fetching an Upwork job detail while the browser session is unauthenticated or expired: the store probe returns with onLogin truthy because the SPA redirected to /ab/account-security/login or equivalent.

Common situations: Session expired between commands; private/job-posting pages that require login; cookies cleared by the browser or an extension; running against a job URL while logged out in the connected profile.

Related errors


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