jackwener/OpenCLI · error · ArgumentError

Invalid --from username: ${JSON.stringify(kwargs.from)}

Error message

Invalid --from username: ${JSON.stringify(kwargs.from)}

What it means

ArgumentError from buildSearchQuery when the --from value does not match FROM_USER_PATTERN (a Twitter/X handle of 1-15 letters, digits, or underscores, optionally prefixed with @). The library rejects it before building the query to avoid sending an invalid from: operator to X's search.

Source

Thrown at clis/twitter/search.js:131

 * unit coverage.
 *
 * Behaviour notes:
 * - Trims leading `@` from --from so callers can pass `@alice` or `alice`.
 * - Order is `<query> from:X filter:Y -filter:Z` (matches what X's own search
 *   bar emits when you click the suggestions UI).
 * - Empty <query> with non-empty filters is allowed — the resulting string
 *   is just the operator clauses joined; X handles that fine.
 *
 * @param {string} rawQuery
 * @param {{ from?: string, has?: string, exclude?: string }} kwargs
 * @returns {string}
 */
function buildSearchQuery(rawQuery, kwargs) {
    const parts = [String(rawQuery ?? '').trim()];
    if (kwargs.from) {
        const fromUser = String(kwargs.from).trim().replace(/^@+/, '');
        if (fromUser && !FROM_USER_PATTERN.test(fromUser)) {
            throw new ArgumentError(
                `Invalid --from username: ${JSON.stringify(kwargs.from)}`,
                'Use a Twitter/X handle with 1-15 letters, numbers, or underscores; omit @ or pass @handle.',
            );
        }
        if (fromUser) parts.push(`from:${fromUser}`);
    }
    if (kwargs.has) {
        parts.push(`filter:${kwargs.has}`);
    }
    if (kwargs.exclude) {
        const op = EXCLUDE_TO_OPERATOR[kwargs.exclude];
        if (op) parts.push(op);
    }
    return parts.filter(Boolean).join(' ');
}

/**
 * Resolve which X search tab (`f=` URL param) to land on. `--product` wins

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Use only 1-15 letters, numbers, or underscores for the handle
  2. Strip the @ prefix (it is allowed but optional): --from @jack or --from jack
  3. Remove any URL, display name, or extra characters and pass only the raw handle

Example fix

// before
opencli twitter search cli --from 'Jack Dorsey'
// after
opencli twitter search cli --from jack
Defensive patterns

Strategy: validation

Validate before calling

const FROM_USER_PATTERN = /^[A-Za-z0-9_]{1,15}$/;
function validateFromUser(v) {
  const h = String(v ?? '').trim().replace(/^@+/, '');
  return h.length > 0 && FROM_USER_PATTERN.test(h);
}
if (kwargs.from && !validateFromUser(kwargs.from)) throw new Error('bad --from handle');

Type guard

function isValidHandle(v) { return /^[A-Za-z0-9_]{1,15}$/.test(String(v ?? '').trim().replace(/^@+/, '')); }

Try / catch

try {
  await opencli.twitter.search(q, { from: handle });
} catch (e) {
  if (e.name === 'ArgumentError' && /--from/.test(e.message)) {
    console.error('Handle must be 1-15 letters/digits/underscores, @ optional');
  } else throw e;
}

Prevention

When it happens

Trigger: `opencli twitter search <query> --from <value>` where <value> contains invalid characters (spaces, hyphens, dots, non-Latin chars), is longer than 15 characters, or is empty after stripping leading @ signs.

Common situations: Passing a full URL instead of a handle, passing a display name with spaces ('Jack Dorsey'), typos like '--from jack-dorsey', or shell quoting issues splitting the handle.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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