jackwener/OpenCLI · error · ArgumentError
Invalid tweet URL host: ${value}
Error message
Invalid tweet URL host: ${value} What it means
ArgumentError from parseTweetUrl when the URL parses but its protocol is not https: or its hostname is not a twitter/x.com host (isTwitterHost). Only https://(www.)(x.com|twitter.com) URLs are accepted, so other schemes/hosts are rejected before extracting the tweet ID.
Source
Thrown at clis/twitter/shared.js:61
|| 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 specific
* tweet by status id. Sibling adapters historically inlined ad-hoc article
* lookups that either (a) skipped scoping entirely (silent: act on first
* matching button on a conversation page) or (b) used substring matches like
* `pathname.includes('/status/' + tweetId)` (silent: `/status/123` matchesView on GitHub (pinned to 49907e53dc)
Solutions
- Use an https://x.com/<user>/status/<id> URL (or https://twitter.com/... equivalent)
- Expand t.co short links to the real x.com status URL first
- Change http:// to https:// if the host is otherwise correct
Example fix
// before opencli twitter retweet http://x.com/jack/status/20 // after opencli twitter retweet https://x.com/jack/status/20
Defensive patterns
Strategy: validation
Validate before calling
function isTweetHostUrl(v) {
try {
const u = new URL(String(v).trim());
const okHost = u.hostname === 'x.com' || u.hostname === 'twitter.com' || u.hostname.endsWith('.twitter.com');
return u.protocol === 'https:' && okHost && /\/status\/\d+/.test(u.pathname);
} catch { return false; }
}
if (!isTweetHostUrl(url)) throw new Error('expected https://x.com/<user>/status/<id>'); Type guard
function isHttpsTwitterUrl(v) {
try { const u = new URL(String(v).trim()); return u.protocol === 'https:' && /(^|\.)(x\.com|twitter\.com)$/.test(u.hostname); } catch { return false; }
} Try / catch
try {
await opencli.twitter.retweet(url);
} catch (e) {
if (e.name === 'ArgumentError' && /host/.test(e.message)) {
console.error('Only https://x.com or https://twitter.com status URLs are supported');
} else throw e;
} Prevention
- Use https:// only — rewrite any http:// links
- Expand t.co and other short links before passing
- Only pass x.com/twitter.com status URLs, not mirrors or other sites
- Normalize hosts (strip mobile./www.) with a whitelist check
When it happens
Trigger: Passing http:// (not https), mobile.twitter.com variants outside the accepted suffix set, a t.co short link, a facebook/reddit URL, or javascript:/file: URIs.
Common situations: Copying an http:// link from old logs, pasting a shortened t.co URL from a tweet, pointing at a mirror/ninga-style frontend host, or test fixtures with example.com URLs.
Related errors
- Invalid tweet URL: ${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/d0765cf00b6482a3.
Report an issue: GitHub.