jackwener/OpenCLI · error · EmptyResultError
${message}
Error message
${message} What it means
The catch-all branch: if the message is neither an auth failure, an upstream failure, nor matched by the caller's emptyPattern, it is wrapped as CommandExecutionError('<failureMessage>: <message>') — identical text to the upstream branch but reached via the fallthrough path.
Source
Thrown at clis/tiktok/utils.js:158
export function looksTikTokAuthFailure(message) {
return /\bAUTH_REQUIRED\b|\b(auth|captcha|login|log in|permission|unauthori[sz]ed|forbidden)\b|HTTP\s+(401|403)\b/i.test(String(message || ''));
}
export function looksTikTokUpstreamFailure(message) {
return /\b(API failed|HTTP\s+\d+|invalid JSON|Failed to fetch|network|fetch)\b/i.test(String(message || ''));
}
export function throwTikTokPageContextError(error, { authMessage, emptyPattern, emptyTarget, failureMessage }) {
const message = getErrorMessage(error);
if (looksTikTokAuthFailure(message)) {
throw new AuthRequiredError('tiktok.com', authMessage);
}
if (looksTikTokUpstreamFailure(message)) {
throw new CommandExecutionError(`${failureMessage}: ${message}`);
}
if (emptyPattern.test(message)) {
throw new EmptyResultError(emptyTarget, message);
}
throw new CommandExecutionError(`${failureMessage}: ${message}`);
}
// Sentinels emitted by Route 1 (button-walker) IIFEs and mapped here to
// typed errors. Keeping the strings constant in one place makes the IIFE
// `throw new Error(...)` callsites greppable and the mapper exhaustive.
export const BUTTON_WALKER_SENTINELS = {
AUTH_REQUIRED: 'AUTH_REQUIRED',
BUTTON_NOT_FOUND: 'BUTTON_NOT_FOUND',
STATE_VERIFY_FAIL: 'STATE_VERIFY_FAIL',
RATE_LIMITED: 'RATE_LIMITED',
};
// Retryability for write-class typed errors. Captured in the hint string
// so the human-readable output makes the retry contract explicit and
// downstream agents/scripts can grep for `retryable=true|false`.
//View on GitHub (pinned to 49907e53dc)
Solutions
- Read the wrapped message — it contains the original error text and points to the real cause
- Update the CLI/scraper if TikTok changed its page structure
- Widen or fix emptyPattern in the calling command if 'empty' cases are misrouted here
- Retry once; transient oddities can produce one-off unrecognized messages
Defensive patterns
Strategy: try-catch
Type guard
const isCommandExecutionError = (e) => e?.name === 'CommandExecutionError' || e instanceof CommandExecutionError;
Try / catch
try { await cli.listUserVideos(u); } catch (e) { console.error('Upstream detail:', e.message); if (isCommandExecutionError(e)) reportToMaintainer(e.message); throw e; } Prevention
- Log the full wrapped message — the original cause is embedded after the prefix
- Keep the CLI updated for TikTok page-markup changes
- Audit emptyPattern regexes in your command configs so empty cases route correctly
When it happens
Trigger: Page-context listing fails with an unrecognized message that does not match the auth pattern, the upstream pattern, or the supplied emptyPattern — e.g. unexpected DOM/selector errors, 'button not found', or new TikTok page variants.
Common situations: TikTok redesigning page markup so selectors fail; unexpected interstitials (captcha variant not matching upstream patterns); a bug in the caller's emptyPattern regex.
Related errors
- Unexpected Dribbble identity response: ${JSON.stringify(resu
- Unexpected Boss probe: ${JSON.stringify(probe)}
- Failed to fetch Douyin comments for video ${awemeId}: ${erro
- hltv match-map parser returned an unexpected shape
- Unexpected Reuters probe: ${JSON.stringify(probe)}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/8158ec39646cac70.
Report an issue: GitHub.