jackwener/OpenCLI · warning · EmptyResultError
No messages found for ${threadId}
Error message
No messages found for ${threadId} What it means
After resolving the thread and fetching it, the command parses messages and slices to the limit; if the parsed list is empty it throws EmptyResultError('linkedin salesnav-thread', `No messages found for ${threadId}`). It fires when the thread object yielded no parseable messages even though a thread id was resolved.
Source
Thrown at clis/linkedin/salesnav-thread.js:196
args: [
{ name: 'thread-or-recipient', type: 'string', required: true, positional: true, help: 'Sales Navigator inbox URL/thread id, Sales Navigator lead URL, recipient urn, or exact participant name' },
{ name: 'limit', type: 'number', default: DEFAULT_MESSAGE_LIMIT, help: 'Maximum messages to return (1-500)' },
{ name: 'max-pages', type: 'number', default: 30, help: 'Maximum inbox pages to scan when resolving a recipient' },
],
columns: ['index', 'thread_id', 'thread_url', 'sender', 'text', 'timestamp', 'subject', 'message_id', 'sender_urn', 'delivered_at', 'type', 'total_message_count'],
func: async (page, args) => {
if (!page) throw new CommandExecutionError('Browser session required for linkedin salesnav-thread');
const input = normalizeWhitespace(args['thread-or-recipient']);
if (!input) throw new ArgumentError('thread-or-recipient is required');
const limit = parseLimit(args.limit, DEFAULT_MESSAGE_LIMIT);
const maxPages = parseLimit(args['max-pages'], 30);
await page.goto(SALES_INBOX_URL);
await page.wait(4);
const threadId = await resolveThreadId(page, input, { maxPages });
const csrf = await getCsrf(page);
const thread = await fetchThreadWithPagination(page, csrf, threadId, limit);
const messages = parseSalesnavThreadMessages(thread).slice(0, limit);
if (messages.length === 0) throw new EmptyResultError('linkedin salesnav-thread', `No messages found for ${threadId}`);
return messages.map((message) => ({
...message,
thread_url: salesnavThreadUrl(threadId),
total_message_count: Number(thread?.totalMessageCount || messages.length),
}));
},
});
export const __test__ = {
parseThreadInput,
threadApiUrl,
participantIndex,
parseSalesnavThreadMessages,
threadMatchesInput,
salesnavThreadUrl,
};
View on GitHub (pinned to 49907e53dc)
Solutions
- Retry the command once to rule out a transient empty API response.
- Open the thread in Sales Navigator to confirm it actually has messages.
- Inspect the raw thread API response and update parseSalesnavThreadMessages if LinkedIn changed the message schema.
- Use a different, known-good thread id to isolate whether the parser or the thread is at fault.
Example fix
// before
const messages = parseSalesnavThreadMessages(thread) // [] on schema drift
// after
const messages = parseSalesnavThreadMessages(thread)
if (messages.length === 0 && Array.isArray(thread?.messages) && thread.messages.length > 0) {
console.warn('parser produced 0 messages from non-empty thread; check schema')
} Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
function hasMessages(t){ return Array.isArray(t?.messages) && t.messages.length > 0; } Try / catch
try { msgs = await fetch() } catch (e) { if (e instanceof EmptyResultError && /No messages found/.test(e.message)) { msgs = []; /* return empty result set deliberately */ } else throw e; } Prevention
- Verify the thread has visible messages in Sales Navigator before automation.
- Retry once to rule out transient empty responses.
- Keep the parser in sync with the LinkedIn thread API schema.
- Log the raw thread payload when this error occurs to detect schema drift.
When it happens
Trigger: The thread API returned a thread whose messages array is empty or in an unexpected shape (e.g. new message types or schema change the parser doesn't recognize), or a brand-new/empty thread was passed.
Common situations: Pointing at a thread with zero retrievable messages; LinkedIn messaging API response shape changed so parseSalesnavThreadMessages returns []; transient empty API response on the first fetch; passing a stale/deleted thread id that still resolves.
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
- linkedin salesnav-search
- No Sales Navigator thread matched ${input}
- dianping search parser found no result-shaped shop cards
- no trending repositories for language "${language}" (${since
- No LinkedIn Learning results for "${keywords}"
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/4a879e0e4e75301e.
Report an issue: GitHub.