jackwener/OpenCLI · error · CommandExecutionError

weread-official ${apiName} returned errcode=${errcode}

Error message

weread-official ${apiName} returned errcode=${errcode}

What it means

The gateway returned a non-zero errcode that is not an auth code. callGateway surfaces it as CommandExecutionError so the caller can react to the specific business error (bad parameter, no such resource, rate limit, permission, etc.).

Source

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

        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);
    if (!Number.isFinite(seconds) || seconds <= 0) return '';
    const date = new Date(seconds * 1000);
    if (Number.isNaN(date.getTime())) return '';
    const y = date.getUTCFullYear();
    const m = String(date.getUTCMonth() + 1).padStart(2, '0');

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Read the errmsg detail for the exact business reason.
  2. Correct the request parameters (validate bookId via requireBookId, non-empty query via requireText).
  3. Back off and retry if the errcode indicates rate limiting.
  4. Consult the WeRead gateway errcode table for this api_name.
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-validate inputs that commonly cause business errcodes
if (!/^[A-Za-z0-9_-]+$/.test(bookId)) throw new Error(`Invalid bookId: ${bookId}`);
if (!query || !query.trim()) throw new Error('Query cannot be empty');

Type guard

const isBusinessError = (e) => e instanceof CommandExecutionError && /errcode=\d+/.test(e.message);

Try / catch

try {
  return await callGateway(apiName, params);
} catch (e) {
  const m = /errcode=(\d+)/.exec(e.message ?? '');
  if (m) {
    console.error(`Gateway business error ${m[1]}: ${e.detail ?? e.message}`);
    if (['429','-1'].includes(m[1])) await sleep(5000); // throttle-style codes
  }
  throw e;
}

Prevention

When it happens

Trigger: Any business-level rejection: invalid bookId, query syntax the API rejects, exceeding quota/rate limits, requesting a resource the account cannot access — whatever errmsg the gateway attached.

Common situations: Passing a bookId copied from a URL instead of from `weread-official search`; requesting highlights for a book not in the account; hammering the API and tripping errcode-based throttling.

Related errors


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