ErrLookup › Background articles › EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows
EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows
EmptyResultError, "No tasks match the specified criteria", "no pins found", and similar "empty result set" errors are thrown when a request completes successfully — no network failure, no auth problem — but the returned data is an empty list: zero rows, zero items, zero messages. This page explains why libraries turn empty results into typed errors instead of returning [], what actually caused the emptiness, and how to handle it as an expected 'no data' outcome.
Distilled from 245 documented records across 9 repositories.
Background
The empty-result-set family sits at the boundary between 'the call worked' and 'there is nothing to show'. In every record, the underlying request succeeded: the HTTP call returned 200, the page rendered, the JSON parsed. What failed — if it can be called a failure — is that the collection was empty. Instead of returning an empty array and letting the caller print an empty table, libraries in this family raise a typed error: OpenCLI throws EmptyResultError with an EMPTY_RESULT exit code distinct from CommandExecutionError (malformed payloads), claude-task-master's ExportService returns a non-throwing NO_TASKS result, Rocket.Chat converts a zero pruned-message count into a translated error toast, and Vagrant's box prune prints a warning and ends without reaching its success line. The common intent is to make 'no data' explicit and distinguishable from the two failure modes it most resembles: broken scraping (selector drift, unrendered DOM) and broken requests (auth walls, network errors).
The layer that produces the error varies. Some libraries check the data at the API boundary: Stack Overflow's /questions/{id} endpoint returns a 200 envelope with an empty items array instead of a 404 for missing questions, and the CLI surfaces 'Question not found' as a typed empty result. Others check after DOM scraping: the Ctrip flight and ferry commands throw only when renderedCardCount is 0, so a page that rendered cards but failed parsing gets a different error; Booking.com's hotel search additionally inspects the page's result-count text before concluding the results are genuinely empty. Others still inspect local state: Trae SOLO's extensions-list throws EmptyResultError when extensions.json exists, parses, and contains an empty array — explicitly 'file OK, zero extensions', distinct from the missing-file error. Some checks are semantic: powerchina search throws when extraction produced rows but all of them were site-navigation chrome rather than real bid entries, and Discord's thread-read treats an empty message list as a failed read because a thread must contain at least its originating message.
From the caller's side, the signal is designed to be branchable. OpenCLI records repeatedly document err.code === 'EMPTY_RESULT' as an expected skip path in batch scripts — the Xiaohongshu notes crawler even instructs consumers to exclude empty-author errors from softFail and rate-limit accounting, and the boss chatmsg command treats the error as the end-of-pagination signal. The libraries disagree on one point deliberately: whether empty is an exception or a soft result. OpenCLI throws a typed exception almost everywhere; claude-task-master returns a failure result without throwing; Rocket.Chat and Vagrant surface a warning or toast and continue. Treat that as library-specific and check the contract of the library you use.
The underlying causes cluster into a few shapes across the nine repositories. The data genuinely does not exist: a Xianyu account with no conversations, a Bilibili video with no subtitle tracks, an empty Pinterest board, a flight route with no service on those dates, two HLTV players with no shared match in the requested window. The query or filter excludes everything: a too-narrow Sales Navigator keyword, an export status filter matching no tasks, prune filters that match zero messages. And the session cannot see data that does exist: an unauthenticated browser where Discord's sidebar or TikTok's notifications would render, a Pixiv safe-mode filter returning empty page lists for restricted works, an expired cookie replaced by a login wall. The first two are true empty results; the third is an empty result that mimics one, which is why several libraries pair the error with hints about checking the same page in a real browser.
Common causes
- The data genuinely does not exist. The account, board, video, route, or page simply has no content: no inbox conversations, no subtitle tracks, no pins in the board, no round-trip flights on those dates, no shared map between two players. This is the intended, healthy trigger for the error — the correct response is to treat it as a 'no data' outcome and skip, not retry.
- Filters or query terms exclude everything. A status filter matches no tasks (claude-task-master export), prune filters match zero messages (Rocket.Chat), --unread-only / --job-id / price-or-city filters remove all rows, or long exact-phrase keywords match no Sales Navigator leads. Broadening the query or filter usually resolves it.
- Page number or pagination beyond the end. Requesting a page past the last one — boss chatmsg --page N beyond the available 20-message pages, or a --page exceeding available recruiter chat pages — returns an empty list. OpenCLI's BOSS records explicitly recommend using this error as the end-of-pagination signal.
- Unauthenticated or expired session hides existing data. The scraper's browser is not logged in, cookies are missing or expired, or a login/bot wall replaced the content DOM: Discord's guild sidebar renders nothing, TikTok notifications come back empty, protected tweets or private Xiaohongshu accounts return empty lists. The result looks like 'no data' but is really an access problem — verify in a real browser with the same account.
- Content not yet rendered when the scraper ran. The in-page script executed before the app finished loading: Discord threads or server lists scraped after too short a wait, Codex diff selectors matched before a review ran, Qoder's sidebar collapsed or on a screen that hides the quest list. Longer timeouts or re-running after full load fixes it.
- Selector or markup drift. The site or app updated its DOM and the extractor's querySelectors now match zero rows, so extraction silently returns an empty array — X media nodes, Discord forum grids, Qoder sidebar class names, powerchina filter hints. If data is clearly visible in a real browser, suspect stale selectors and update the tool.
- Wrong identifier or wrong source. A nonexistent or deleted Stack Overflow question (the API returns an empty items array instead of a 404), an id from a different Stack Exchange site, a wrong Pinterest slug resolving to a different empty board, a deleted/closed shop page, or the wrong TRAE profile whose extensions.json is legitimately empty. Validate ids and targets before invoking.
- Access restrictions that return empty instead of forbidden. Deleted/restricted Pixiv works hidden by safe-mode or R-18 filters return empty page lists, closed or removed Stack Exchange posts are invisible to anonymous callers, and geo/risk-control gating (Ctrip) can blank the page. Some APIs prefer empty 200s to auth errors, so emptiness can mask a permission issue.
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
- No Xianyu inbox conversations were found (jackwener/OpenCLI)
- ${command} page loaded but no matching rows were found (jackwener/OpenCLI)
- dianping ${contextHint} (jackwener/OpenCLI)
- NO_TASKS: No tasks match the specified criteria (eyaltoledano/claude-task-master)
- ctrip flight-round (jackwener/OpenCLI)
- No recruiter-side chat sessions were returned. (jackwener/OpenCLI)
- 此视频没有发现外挂或智能字幕。 (jackwener/OpenCLI)
- discord-app servers (jackwener/OpenCLI)
- No round-trip flights for ${fromCode} to ${toCode} on ${depart} .. ${ret} (jackwener/OpenCLI)
- attached ? t('No_files_found_to_prune') : t('No_messages_found_to_prune') (RocketChat/Rocket.Chat)
- No sailings for ${fromCity} to ${toCity} on ${date} (jackwener/OpenCLI)
- no pins found in board "${username}/${slug}" (jackwener/OpenCLI)
- powerchina search (jackwener/OpenCLI)
- twitter download ${target.id} (jackwener/OpenCLI)
- No images found for illustration ${row.illust_id}. (jackwener/OpenCLI)
- qoder history (jackwener/OpenCLI)
- Question not found (jackwener/OpenCLI)
- EMPTY_RESULT: 该用户没有公开笔记(可能销号 / 私密 / 全部删除)。 (jackwener/OpenCLI)
- No posts found in this Band (jackwener/OpenCLI)
- discord-app thread-read (jackwener/OpenCLI)
…and 225 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.