jackwener/OpenCLI · error · ArgumentError

thread-or-recipient is required

Error message

thread-or-recipient is required

What it means

The command's func normalizes the positional 'thread-or-recipient' argument with normalizeWhitespace; if the result is an empty string it throws ArgumentError('thread-or-recipient is required'). This is the top-level argument check and mirrors the deeper resolveThreadId 'empty' guard (error 2400) but fires before any page navigation.

Source

Thrown at clis/linkedin/salesnav-thread.js:187

cli({
  site: 'linkedin',
  name: 'salesnav-thread',
  access: 'read',
  description: 'Return full Sales Navigator message history for a thread id, Sales Navigator inbox URL, lead URL, recipient urn, or exact recipient name',
  domain: LINKEDIN_DOMAIN,
  strategy: Strategy.UI,
  browser: true,
  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__ = {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Provide the positional thread-or-recipient value (inbox URL, thread id, lead URL, recipient URN, or participant name).
  2. Trim the value; whitespace-only input is rejected.
  3. Guard calling scripts so they abort when the value is empty.
  4. Use the CLI's --help to confirm the positional arity.

Example fix

// before
node cli.js linkedin salesnav-thread            # missing positional
// after
node cli.js linkedin salesnav-thread "https://www.linkedin.com/sales/inbox/5918503635263671296"
Defensive patterns

Strategy: validation

Validate before calling

const v = (args['thread-or-recipient'] ?? '').trim(); if (!v) throw new Error('usage: linkedin salesnav-thread <inbox-url|thread-id|lead-url|urn|name>');

Type guard

function isNonEmptyString(v){ return typeof v === 'string' && v.trim().length > 0; }

Try / catch

try { await cli() } catch (e) { if (e instanceof ArgumentError && e.message === 'thread-or-recipient is required') { process.exitCode = 2; console.error(e.message); } else throw e; }

Prevention

When it happens

Trigger: Invoking linkedin salesnav-thread with no positional argument, an empty string, or a whitespace-only string.

Common situations: Forgetting the positional argument on the command line; a build script interpolating an empty variable; quoting mistakes so the shell drops the argument; passing args as named flags instead of the required positional.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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