jackwener/OpenCLI · error · ArgumentError
${label} must be an exact https://www.linkedin.com/messaging
Error message
${label} must be an exact https://www.linkedin.com/messaging/thread/<id>/ URL What it means
requireLinkedInThreadUrl canonicalizes the input via canonicalizeLinkedInThreadUrl and throws ArgumentError when the value does not canonicalize to an exact https://www.linkedin.com/messaging/thread/<id>/ URL. The URL must match LinkedIn's messaging thread pattern precisely — other paths, hosts, or extra fragments fail.
Source
Thrown at clis/linkedin/thread-snapshot.js:20
import { ArgumentError, AuthRequiredError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';
import {
canonicalizeLinkedInThreadUrl,
normalizeWhitespace,
requireLinkedInCookie,
unwrapEvaluateResult,
} from './shared.js';
const LINKEDIN_DOMAIN = 'www.linkedin.com';
function requireStringArg(args, key, label = key) {
const value = normalizeWhitespace(args[key]);
if (!value) throw new ArgumentError(`${label} is required`);
return value;
}
function requireLinkedInThreadUrl(value, label) {
const url = canonicalizeLinkedInThreadUrl(value);
if (!url) throw new ArgumentError(`${label} must be an exact https://www.linkedin.com/messaging/thread/<id>/ URL`);
return url;
}
function parseMaxScrolls(value) {
if (value === undefined || value === null || value === '') return 30;
const scrolls = Number(value);
if (!Number.isInteger(scrolls) || scrolls < 0 || scrolls > 80) {
throw new ArgumentError('--max-scrolls must be an integer between 0 and 80');
}
return scrolls;
}
function buildThreadApiDiscoveryScript(maxScrolls) {
return String.raw`(async () => {
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const pageText = document.body ? (document.body.innerText || '') : '';
const authRequired = /\b(sign in|log in|join linkedin)\b/i.test(pageText)
|| /linkedin\.com\/(login|checkpoint|authwall|uas)/i.test(location.href)View on GitHub (pinned to 49907e53dc)
Solutions
- Copy the full URL while viewing the thread: https://www.linkedin.com/messaging/thread/<threadId>/.
- Remove query strings/extra fragments; ensure https and the www.linkedin.com host.
- Fix truncation/encoding of the thread ID (long alphanumeric string).
- Verify the shape before calling with a regex like /^https:\/\/www\.linkedin\.com\/messaging\/thread\/[A-Za-z0-9-_]+\/$/.
Example fix
// before --thread-url "https://www.linkedin.com/feed/update/urn:li:activity:123/" // after --thread-url "https://www.linkedin.com/messaging/thread/AbCdEf123_/"
Defensive patterns
Strategy: validation
Validate before calling
const THREAD_URL_RE = /^https:\/\/www\.linkedin\.com\/messaging\/thread\/[A-Za-z0-9_-]+\/$/;
function isValidThreadUrl(u) {
return typeof u === 'string' && THREAD_URL_RE.test(u.trim());
}
if (!isValidThreadUrl(threadUrl)) throw new Error('Pass an exact https://www.linkedin.com/messaging/thread/<id>/ URL'); Type guard
function isLinkedInThreadUrl(v) {
if (typeof v !== 'string') return false;
try {
const u = new URL(v);
return u.protocol === 'https:' && u.hostname === 'www.linkedin.com' &&
/^\/messaging\/thread\/[A-Za-z0-9_-]+\/$/.test(u.pathname);
} catch { return false; }
} Try / catch
try {
await threadSnapshot({ 'thread-url': threadUrl });
} catch (e) {
if (e instanceof ArgumentError && e.message.includes('messaging/thread')) {
console.error('Not a valid thread URL. Copy it from an open LinkedIn message thread.');
} else throw e;
} Prevention
- Copy the URL directly from an open messaging thread; it must contain /messaging/thread/<id>/.
- Strip query strings and ensure the www host with https.
- Check the thread ID is not truncated or URL-mangled by your tooling.
- Pre-validate with the regex above before invoking the command.
When it happens
Trigger: Passing a profile or feed URL instead of a messaging thread URL, a thread URL without the ID, a URL with extra path segments or query strings that fail canonicalization, a non-www host, or http instead of https.
Common situations: Copying the wrong URL from the browser (post/feed instead of thread), URL-encoding mangling the ID, using a mobile or short-link form, truncated thread ID from logs.
Related errors
- ${label} must point to linkedin.com
- LinkedIn company URL must point to linkedin.com
- LinkedIn company URL must look like /company/<name>
- LinkedIn company URL has a malformed company slug: ${m[1]}
- LinkedIn company name has unexpected characters: ${slug}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/6d3ee3415bd658a9.
Report an issue: GitHub.