ErrLookup › Background articles › EmptyResultError: What the EMPTY_RESULT Error Code Means and How to Fix It
EmptyResultError: What the EMPTY_RESULT Error Code Means and How to Fix It
EmptyResultError (error code EMPTY_RESULT) is a typed error thrown when a command or API call succeeded but returned no usable data — an empty array, a blank payload, a page that rendered nothing, or a 404 on a lookup. Developers usually meet it when scripting CLI commands or automation wrappers around web pages and APIs: the run did not crash and was not blocked, but there was genuinely nothing to return, and the library refuses to hand back an empty result that could be mistaken for success.
Distilled from 434 documented records across 2 repositories.
Background
EmptyResultError is a deliberate design choice: it separates 'no data' from 'broken command'. In the OpenCLI codebase it carries the code EMPTY_RESULT and sits alongside CommandExecutionError (malformed payloads, parse failures, selector drift) and AuthRequiredError (login walls). Because the distinction is encoded in the error type, callers can branch on err.code: an empty result is typically an expected, skip-able outcome that skips retries and soft-fail counting, while a command execution error is a real bug worth retrying or alerting on. Several commands map it to a dedicated EMPTY_RESULT exit code so shell scripts can treat 'no data' as a normal branch.
The error is produced at the boundary between a command and its data source, and the triggers fall into recognizable groups. Some are pure data conditions: a CoinGecko markets request that legitimately returns [], a Lobste.rs domain endpoint that answers 404 because the domain has never been submitted, an npm registry 404 for a nonexistent or unpublished package, an empty Xianyu inbox, or a board with no pins. Others are browser-scraping conditions: the page loaded, the selector matched, but zero rows were extracted — zero flight cards on Ctrip or Trip.com, no visible Gemini turns, no Copy buttons on an Antigravity reply, or a Tieba thread page whose extraction yielded no posts. A third group guards against silent mis-navigation: the Tieba read command asserts the landed URL actually contains the requested thread id and page number, throwing EmptyResultError rather than returning content from the wrong thread. Finally, some variants fire when a response technically parsed but carries no real data — an item-detail object with no title, a evaluate result of null, or a page whose rows were all filtered out as navigation chrome.
What it looks like from the caller's side varies by command. The constructor often takes a command label as its first argument, so messages read like '<command> returned no data', and many variants attach a hint field (err.hint) with an actionable next step, such as 'The page structure may have changed, or you may need to log in'. Some messages embed the upstream cause — the Goofish API's own error_message, a tweet id, a route/date pair, or a domain name — so the error text is often enough to diagnose the run without opening the source.
Because this family is documented from a single repository, the behavior described here is specific to OpenCLI's conventions: every record treats EmptyResultError as the typed signal for a successful operation with nothing to return. Notably, the boundary between 'empty' and 'blocked' or 'auth-walled' is command-specific — for example, Bilibili subtitles hidden behind a login throw AuthRequiredError while genuinely subtitle-less videos throw EmptyResultError, and Xianyu risk-control interception surfaces as EmptyResultError with a 'blocked by verification' hint rather than an auth error. When adapting these patterns, check each command's own error mapping rather than assuming one rule.
Common causes
- The data source genuinely has no matching rows.The query executed correctly but the source is empty: a search with zero results, a route/date pair with no flights or sailings, a board with no pins, an inbox with no conversations, or a domain never submitted to Lobste.rs. This is the intended, normal use of the error.
- The requested resource does not exist or is gone.HTTP 404s from lookup APIs (npm registry, Lobste.rs domains) and IDs pointing at deleted, unpublished, region-locked, or restricted items. The response parsed fine but names something that is not there.
- Not logged in or the page never rendered.An empty scrape of Discord servers, Gemini turns, or Antigravity Copy buttons usually means the app is signed out, the sidebar/chat has not rendered yet, or the scrape script ran before the UI finished loading.
- Redirected or mis-paginated navigation.The browser landed somewhere other than requested: Tieba redirecting to a captcha/login/home page or snapping back to page 1 when a later page was requested. The library asserts the destination (thread id, pn param) and throws instead of returning wrong data.
- Anti-bot, captcha, or risk-control interception.Goofish/Xianyu item lookups can be intercepted by CAPTCHA or slider verification, and Tieba may serve a challenge wall at the correct URL. Some of these surface as EmptyResultError with a 'blocked' hint rather than a dedicated auth error.
- Selectors or extraction filters matched nothing.After a site UI update, extraction selectors can silently return zero rows even when data is visible, or every extracted row can be filtered out as navigation chrome (e.g. powerchina search). This variant is a library bug masquerading as an empty result.
- Input formatting mistakes.Wrong identifier types or unnormalized inputs: CoinGecko wants coin ids like 'bitcoin' not symbols like 'BTC', scoped npm package names must be URL-encoded (@scope%2fname), unnormalized domains with schemes can 404, and wrong slugs can resolve to a different user's empty board.
What usually fixes it
- [object Object]
- [object Object]
- [object Object]
- [object Object]
- [object Object]
- [object Object]
Go deeper
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
- HTTP status errors: handling 4xx and 5xx responses — how to handle 4xx and 5xx responses properly.
Documented occurrences
- Tieba did not land on the requested thread page(jackwener/OpenCLI)
- No Xianyu inbox conversations were found(jackwener/OpenCLI)
- 该视频没有字幕(作者未开启 + 无自动字幕)。(jackwener/OpenCLI)
- ${command} page loaded but no matching rows were found(jackwener/OpenCLI)
- qoder more-actions(jackwener/OpenCLI)
- Tieba did not land on the requested page(jackwener/OpenCLI)
- chatgpt deep-research-result(jackwener/OpenCLI)
- dianping ${contextHint}(jackwener/OpenCLI)
- antigravity copy-message(jackwener/OpenCLI)
- errorMessage || `Xianyu item detail request failed: ${result.error}`(jackwener/OpenCLI)
- ctrip flight-round(jackwener/OpenCLI)
- No turns were visible after navigating to ${target}.(jackwener/OpenCLI)
- Tieba may have blocked the thread page, or the DOM structure may have changed(jackwener/OpenCLI)
- No Lobste.rs stories found for domain "${domain}".(jackwener/OpenCLI)
- No recruiter-side chat sessions were returned.(jackwener/OpenCLI)
- coingecko top(jackwener/OpenCLI)
- 此视频没有发现外挂或智能字幕。(jackwener/OpenCLI)
- discord-app servers(jackwener/OpenCLI)
- No round-trip flights for ${fromCode} to ${toCode} on ${depart} .. ${ret}(jackwener/OpenCLI)
- npm registry returned 404 for ${url}.(jackwener/OpenCLI)
…and 414 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.