jackwener/OpenCLI · critical · AuthRequiredError

WEREAD_API_KEY rejected (errcode=${errcode}, ${errmsg}). Reg

Error message

WEREAD_API_KEY rejected (errcode=${errcode}, ${errmsg}). Regenerate the key and re-export it.

What it means

The gateway accepted the request (HTTP ok) but returned a business errcode that is in AUTH_ERRCODES, meaning WEREAD_API_KEY was rejected. callGateway throws AuthRequiredError naming the WeRead domain, instructing the key to be regenerated and re-exported.

Source

Thrown at clis/weread-official/utils.js:134

        const detail = error instanceof Error ? error.message : String(error);
        throw new CommandExecutionError(`weread-official ${apiName} returned invalid JSON`, detail);
    }

    if (payload && typeof payload === 'object' && payload.upgrade_info) {
        const info = payload.upgrade_info;
        const required = info?.required_version ?? info?.version ?? 'unknown';
        const message = info?.message ?? 'WeRead skill version is outdated';
        throw new CommandExecutionError(
            `WeRead skill 需升级: ${message}. Required skill_version=${required}, current=${SKILL_VERSION}`,
            'Pull the latest weread-skills.zip and bump SKILL_VERSION in clis/weread-official/utils.js.',
        );
    }

    const errcode = Number(payload?.errcode ?? 0);
    if (errcode !== 0) {
        const errmsg = String(payload?.errmsg ?? 'unknown error');
        if (AUTH_ERRCODES.has(errcode)) {
            throw new AuthRequiredError(
                WEREAD_DOMAIN,
                `WEREAD_API_KEY rejected (errcode=${errcode}, ${errmsg}). Regenerate the key and re-export it.`,
            );
        }
        throw new CommandExecutionError(
            `weread-official ${apiName} returned errcode=${errcode}`,
            errmsg,
        );
    }

    return payload;
}

// ── Formatting helpers ──────────────────────────────────────────────────────

/** Unix timestamp (sec) → YYYY-MM-DD using UTC for stable test snapshots. */
export function formatDate(ts) {
    const seconds = Number(ts);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Regenerate the API key in the WeRead console and copy the new value.
  2. Re-export WEREAD_API_KEY in the current shell (and update CI/secret stores).
  3. Run `weread-official` auth/status check to confirm the new key works.
  4. Ensure no stale key lingers in .env, shell rc files, or credential helpers.

Example fix

// before
export WEREAD_API_KEY=revoked_key
// after
export WEREAD_API_KEY=<regenerated_key>
# then: weread-official search --query test   # to verify
Defensive patterns

Strategy: try-catch

Validate before calling

if (!process.env.WEREAD_API_KEY) throw new Error('WEREAD_API_KEY is missing — export a valid key first');
if (!/^\S{10,}$/.test(process.env.WEREAD_API_KEY)) console.warn('WEREAD_API_KEY looks malformed');

Type guard

const isAuthError = (e) => e instanceof AuthRequiredError || (e instanceof CommandExecutionError && /WEREAD_API_KEY rejected/.test(e.message));

Try / catch

try {
  return await callGateway(apiName, params);
} catch (e) {
  if (e instanceof AuthRequiredError) {
    console.error(`Re-authenticate with ${e.domain}: regenerate WEREAD_API_KEY and re-export it.`);
    process.exitCode = 3; // let automation re-run the auth step
    return null;
  }
  throw e;
}

Prevention

When it happens

Trigger: errcode in AUTH_ERRCODES (e.g. auth/token invalid, key revoked); key deleted from the WeRead console; key past expiry; wrong key exported for the account/domain.

Common situations: Rotating keys and forgetting to re-export in the shell/CI secrets; multiple accounts with mismatched keys; long-lived key expiring while a script runs unattended.

Related errors


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