ErrLookup › Background articles › CommandExecutionError: Command Ran, But the Result Was Wrong — Common Causes and Fixes
CommandExecutionError: Command Ran, But the Result Was Wrong — Common Causes and Fixes
CommandExecutionError is a wrapper error thrown when a CLI command executed but something went wrong during that execution — a failed browser-automation step, an unexpected HTTP status, a malformed API payload, or a scrape that returned nothing the parser recognizes. Developers usually meet it in the jackwener/OpenCLI tooling (codex, reddit, bilibili, twitter, trip/ctrip, archive.org and other site adapters), where the message text after the prefix points at the real failure underneath.
Distilled from 2,073 documented records across 3 repositories.
Background
CommandExecutionError in these records is not an error a remote service returns; it is the CLI's own classification for 'the command I ran failed while running.' It is thrown at the orchestration layer of the OpenCLI command framework, typically with code COMMAND_EXEC and exit code 1, wrapping a lower-level failure whose details are folded into the message. That wrapping is deliberate: raw browser exceptions and in-page script errors are often not serializable or not meaningful on the Node side, so the library normalizes them into a single error whose message embeds the cause (an HTTP status, a JSON envelope code, a probe object, or the inner exception text).
The family covers two broad sub-kinds. The first is transport-level failures: a page.evaluate() call rejected, the browser tab navigated or closed mid-script, the bridge connection dropped, or a fetch rejected before a response arrived (DNS failure, timeout, TLS error, connection reset). The second is result-validation failures: the command completed, but the returned data failed an integrity check — a Codex extract-diff script returned a non-array, a Trip.com payload lacked its grouplist array, an archive.org metadata response had a non-array files field, a Booking.com hotel row lacked a canonical name/slug/URL, or a clicked filter chip never became active. In both cases the library prefers throwing over silently returning empty or corrupted results.
The library distinguishes this family from sibling errors, and that distinction is the key to debugging. Auth problems throw AuthRequiredError (don't re-login on a CommandExecutionError like 'HTTP 429 from /api/auth/session'); legitimately empty search results throw EmptyResultError (as the Ctrip ferry adapter does, reserving CommandExecutionError for 'rows rendered but the parser found nothing'); recognized API auth codes in mubu envelopes are routed to AuthRequiredError while unrecognized codes land here. When you see CommandExecutionError, read the message after the prefix: it usually names the failing step, the endpoint, the HTTP status, or the actual malformed value, and record-specific pages cover each variant in depth.
Because most OpenCLI commands drive live third-party sites through browser automation (Strategy.INTERCEPT network capture, in-page IIFE scrapes, signed-CDN two-step downloads), the dominant failure modes are environmental: page context destroyed mid-evaluate, Cloudflare or anti-bot interstitials, markup drift after a site redesign, and rate-limiting on shared egress IPs. Several variants also carry their own embedded diagnostics — lastAttribute for Bilibili relation polls, the serialized probe JSON for Linux.do verification, available=[...] model labels for Trae — so the message itself is usually the fastest diagnostic.
Common causes
- Page context destroyed during evaluate.The tab navigated, closed, or crashed while an in-page script ran, so page.evaluate resolves to null/undefined instead of a structured result. This is the most frequently cited trigger (Codex extract-diff, Linux.do probe, Reuters search, Zhihu answer extraction, Mercury clickText) and often resolves on a simple retry.
- Upstream site markup or API schema drift.A redesign changes selectors or response shapes: missing __NEXT_DATA__ on Hupu, no grouplist array from Trip.com, hotel rows without canonical URL identity on Booking.com, malformed Pixiv count fields, or Twitter GraphQL payloads that no longer match the parser. Keep the library updated; these variants usually require an extractor fix.
- Anti-bot, captcha, or challenge interstitials.Cloudflare challenges, Datadome walls, robot-check pages, or degraded consent pages replace real content, so extraction finds nothing it recognizes. Datacenter IPs trigger this disproportionately; residential egress and a logged-in, settled session help.
- Non-OK HTTP status from an endpoint.The request completed but the server answered 403 (WAF/IP block), 429 (rate limit), 404 (deleted resource), or 5xx (outage) — surfaced as 'HTTP <status> from <where>'. Back off and retry 429/5xx, change egress IP for 403, and verify identifiers for 404; do not re-login for these.
- Signed URL or session expiring between steps.Multi-step flows can fail between step one and step two: a pre-signed Slock CDN URL whose expiresAt passes before the download, or a session cookie that is present but too stale to authorize the endpoint. Download immediately after resolving signed URLs and refresh sessions before batch runs.
- Polling deadline exceeded before the expected state appeared.Time-boxed waits give up: a Xiaohongshu filter chip not active within 2.5s, a Bilibili relation attribute not flipping within 5s, or Hupu's __NEXT_DATA__ not rendering within 5s. Server lag is often the cause — retry, raise the timeout, or make sure the environment provides a real wait() so the full polling window runs.
- Wrong or invalid input to the command.A model name matching no dropdown label in Trae, a nonexistent GeoGebra object label (case-sensitive), an attachment id that is not a valid existing UUID, or an identifier pointing at a collection instead of an item. The available-options detail embedded in the message usually tells you what would have matched.
- Missing or broken browser wiring.Calling internal helpers without the browser handle ('Browser page required') or running intercept-strategy commands against a page without startNetworkCapture/readNetworkCapture. This is a programming/wiring error, not a site problem — route commands through the CLI's own browser:true entry points.
What usually fixes it
- Read the message after the prefix first: it embeds the failing step, endpoint, HTTP status, error code, or the raw offending value, and usually distinguishes auth (re-login), transient (retry), and drift (update the library) causes.
- Retry with backoff on transient failures — null probes, 429/5xx statuses, polling deadlines, and page-context crashes are the variants most likely to pass on a second run; only retry 429/5xx statuses, not permanent shapes.
- Keep the CLI updated and smoke-test after site changes: markup and schema drift across Booking.com, Trip.com, Hupu, Twitter, and Ctrip is a leading cause, and fixes land in new releases rather than in configuration.
- Run commands through the CLI's own browser entry points with a logged-in, settled session; avoid concurrent navigation, serialize commands from one IP, and prefer residential egress to avoid challenges and WAF blocks.
- Log raw payloads (page.evaluate results, upstream JSON, raw HTML) when the error fires — several records explicitly recommend capturing the actual response before the throw to diagnose whether you are seeing a captcha wall, an error envelope, or a schema change.
Go deeper
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
- Connection failures: ECONNREFUSED, ECONNRESET, and friends — why connections get refused, reset, or dropped.
- HTTP status errors: handling 4xx and 5xx responses — how to handle 4xx and 5xx responses properly.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Documented occurrences
- Codex extract-diff returned an invalid payload.(jackwener/OpenCLI)
- Unexpected Linux.do probe: ${JSON.stringify(probe)}(jackwener/OpenCLI)
- HTTP ${result.httpStatus} from ${result.where}(jackwener/OpenCLI)
- Booking.com hotel row is missing stable name/url identity(jackwener/OpenCLI)
- ${reason}${detail}(jackwener/OpenCLI)
- No model matched: '${name}'(jackwener/OpenCLI)
- Zhihu answer download request failed: ${error instanceof Error ? error.message : String(error)}(jackwener/OpenCLI)
- YouTube video metadata is missing membersOnly(jackwener/OpenCLI)
- Reuters search API returned an unreadable response(jackwener/OpenCLI)
- Xiaohongshu search filter chip did not become active (${detail}).(jackwener/OpenCLI)
- Failed to read GeoGebra object property: ${err?.message || err}(jackwener/OpenCLI)
- Failed to fetch Xiaoyuzhou transcript content: ${getErrorMessage(error)}(jackwener/OpenCLI)
- WeChat create-draft failed: ${message}(jackwener/OpenCLI)
- HTTP ${res.status} from signed CDN URL while downloading ${id}(jackwener/OpenCLI)
- Ctrip ferry rows rendered but parser did not find required sailing anchors(jackwener/OpenCLI)
- Bilibili relation modify did not verify ${expectedLabel}; last attribute=${lastAttribute}(jackwener/OpenCLI)
- Ctrip flight requires browser response interception(jackwener/OpenCLI)
- Twitter UserMedia returned GraphQL errors: ${JSON.stringify(payload.errors).slice(0, 200)}(jackwener/OpenCLI)
- mubu: ${path}: code=${data.code} ${data.message ?? ''}(jackwener/OpenCLI)
- Twitter lists returned an unexpected payload shape(jackwener/OpenCLI)
…and 2,053 more across the corpus — use search.
Honest provenance: generated on 2026-08-29 from AI-assisted analysis of the linked records. See how records are made.