jackwener/OpenCLI · error · ArgumentError
Invalid tweet URL: ${value}
Error message
Invalid tweet URL: ${value} What it means
ArgumentError from parseTweetUrl when the string is non-empty but cannot be parsed as a URL (new URL(value) throws). The library rejects it early with guidance to use a full https://x.com/<user>/status/<id> URL.
Source
Thrown at clis/twitter/shared.js:57
]);
function isTwitterHost(hostname) {
return TWEET_HOSTS.has(hostname)
|| hostname.endsWith('.x.com')
|| hostname.endsWith('.twitter.com');
}
export function parseTweetUrl(rawUrl) {
const value = String(rawUrl ?? '').trim();
if (!value) {
throw new ArgumentError('twitter tweet URL cannot be empty', 'Example: opencli twitter retweet https://x.com/jack/status/20');
}
let parsed;
try {
parsed = new URL(value);
}
catch {
throw new ArgumentError(`Invalid tweet URL: ${value}`, 'Use a full https://x.com/<user>/status/<id> URL');
}
const hostname = parsed.hostname.toLowerCase();
if (parsed.protocol !== 'https:' || !isTwitterHost(hostname)) {
throw new ArgumentError(`Invalid tweet URL host: ${value}`, 'Use a full https://x.com/<user>/status/<id> URL');
}
const match = parsed.pathname.match(TWEET_PATH_PATTERN);
if (!match?.[1]) {
throw new ArgumentError(`Could not extract tweet ID from URL: ${value}`, 'Use a full https://x.com/<user>/status/<id> URL');
}
return {
id: match[1],
url: parsed.toString(),
};
}
/**
* Build a JS source fragment that, when embedded inside a `page.evaluate(...)`
* IIFE, declares browser-side helpers for scoping operations to a specificView on GitHub (pinned to 49907e53dc)
Solutions
- Use the full URL including https:// scheme
- If you only have the ID, build the URL: `https://x.com/<user>/status/<id>` or `https://x.com/i/status/<id>` if supported
- Trim whitespace/newlines from the input before passing
Example fix
// before opencli twitter retweet 20 // after opencli twitter retweet https://x.com/jack/status/20
Defensive patterns
Strategy: validation
Validate before calling
function normalizeTweetUrl(v) {
const s = String(v ?? '').trim();
if (/^\d+$/.test(s)) return `https://x.com/i/status/${s}`; // bare ID
if (!/^https:\/\//.test(s)) return `https://${s}`;
return s;
}
// then verify: new URL(normalizeTweetUrl(v)) does not throw Type guard
function isParseableUrl(v) { try { new URL(String(v).trim()); return true; } catch { return false; } } Try / catch
try {
await opencli.twitter.retweet(url);
} catch (e) {
if (e.name === 'ArgumentError' && /Invalid tweet URL:/.test(e.message)) {
console.error('Use https://x.com/<user>/status/<id>');
} else throw e;
} Prevention
- Always include the https:// scheme
- Expand bare tweet IDs to full URLs in your wrapper
- Trim whitespace/newlines from pasted input
- Validate with new URL() before calling the CLI
When it happens
Trigger: Passing 'jack/status/20', 'x.com/jack/status/20' (no scheme is actually parseable by URL only with base — bare host without scheme throws), 'opencli twitter retweet 20' (just the ID), or a URL with stray spaces.
Common situations: Users pasting just the tweet ID or path from the address bar minus scheme, shell mangling, or code passing a tweet object instead of its URL string.
Related errors
- Invalid tweet URL host: ${value}
- Invalid clip-id: ${raw}
- twitter profile username must be a valid Twitter/X handle
- Invalid --from username: ${JSON.stringify(kwargs.from)}
- twitter search query is empty
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/45a0b97eed00bc2c.
Report an issue: GitHub.