jackwener/OpenCLI · warning · EmptyResultError

EMPTY_RESULT

EMPTY_RESULT

Error message

该用户没有公开笔记(可能销号 / 私密 / 全部删除)。

What it means

After scrolling/paginating the user's notes, zero notes were collected, so the command throws EmptyResultError with code EMPTY_RESULT. Per the source comment, an author with no public notes (deactivated account, private account, or all notes deleted) is a legitimate empty-data condition, not a fetch failure — downstream consumers should recognize the code and skip rate-limit heuristics and softFail counting.

Source

Thrown at clis/xiaohongshu/user.js:136

        for (let i = 0; results.length < limit && i < 4; i += 1) {
            await page.autoScroll({ times: 1, delayMs: 1500 });
            await page.wait(1);
            snapshot = await readUserSnapshot(page);
            if (isLoginWallSnapshot(snapshot)) {
                throwLoginWallAuthRequired();
            }
            assertReadableUserSnapshot(snapshot);
            const nextResults = extractXhsUserNotes(snapshot ?? {}, userId);
            if (nextResults.length <= previousCount)
                break;
            results = nextResults;
            previousCount = nextResults.length;
        }
        if (results.length === 0) {
            // 与 bilibili subtitle 同模式:作者无公开内容是合法 empty 数据条件
            // (销号 / 私密号 / 全删笔记),不是 fetch 失败。下游应识别 code
            // EMPTY_RESULT 跳过 rate-limit 启发式、不计入 softFail 阈值。
            throw new EmptyResultError('xiaohongshu user', '该用户没有公开笔记(可能销号 / 私密 / 全部删除)。');
        }
        return results.slice(0, limit);
    },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Treat code EMPTY_RESULT as a skip, not a failure: check err.code === 'EMPTY_RESULT' in your handler and continue
  2. Verify the user's profile in a browser to confirm the account is really empty/private rather than blocked
  3. If you expected notes, check whether login is required to see them and refresh the session
  4. Catch EmptyResultError separately from CommandExecutionError in your pipeline

Example fix

// before
try { notes = await userCommand.run({ userId }); }
catch (err) { console.error(err); }
// after
try { notes = await userCommand.run({ userId }); }
catch (err) {
  if (err.code === 'EMPTY_RESULT') { skipUser(userId); return; }
  throw err;
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const notes = await getUserNotes(userId);
} catch (err) {
  if (err.code === 'EMPTY_RESULT') {
    return []; // legitimate empty: deactivated/private/deleted account — do not count as failure
  }
  throw err;
}

Prevention

When it happens

Trigger: Target user deactivated (销号) their account; account is fully private; user deleted all public notes; or the notes never hydrated across all retry rounds (previousCount stayed 0).

Common situations: Crawling a user URL that was deleted; stale bookmark to a removed account; scraping profiles where notes require login that this session lacks.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


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