jackwener/OpenCLI · error · ArgumentError

nowcoder detail requires a numeric content ID, moment UUID,

Error message

nowcoder detail requires a numeric content ID, moment UUID, or canonical Nowcoder URL

What it means

parseNowcoderPostTarget accepts a numeric content ID, a 32-hex moment UUID, or a canonical Nowcoder URL. When the raw input is none of those and also cannot be parsed by the URL constructor, it throws this ArgumentError telling the user exactly which three input forms are accepted. It is a user-input validation error, not a network or data error.

Source

Thrown at clis/nowcoder/posts.js:187

    for (const record of records) {
        const data = wrapped ? record?.data : record;
        rows.push(projectFeedData(data, rows.length, source === 'experience' || wrapped));
    }
    if (rows.length === 0) throw new EmptyResultError(`nowcoder ${source}`, 'Nowcoder returned no content or moment posts.');
    return rows.slice(0, limit);
}

export function parseNowcoderPostTarget(raw) {
    const value = typeof raw === 'string' ? raw.trim() : '';
    if (NUMERIC_ID_PATTERN.test(value)) return { post_type: 'content', value };
    if (UUID_PATTERN.test(value)) return { post_type: 'moment', value: value.toLowerCase() };

    let url;
    try {
        url = new URL(value);
    }
    catch {
        throw new ArgumentError('nowcoder detail requires a numeric content ID, moment UUID, or canonical Nowcoder URL');
    }
    const host = url.hostname.toLowerCase();
    if (url.protocol !== 'https:' || url.username || url.password || url.port || url.hash
        || (host !== 'nowcoder.com' && host !== 'www.nowcoder.com')) {
        throw new ArgumentError('nowcoder detail only accepts canonical https://www.nowcoder.com post URLs');
    }
    const content = url.pathname.match(/^\/discuss\/([1-9]\d*)\/?$/);
    if (content) return { post_type: 'content', value: content[1] };
    const moment = url.pathname.match(/^\/feed\/main\/detail\/([0-9a-f]{32})\/?$/i);
    if (moment) return { post_type: 'moment', value: moment[1].toLowerCase() };
    throw new ArgumentError('Unsupported Nowcoder URL; expected /discuss/<content-id> or /feed/main/detail/<moment-uuid>');
}

export function projectNowcoderDetail(data, target) {
    if (!isRecord(data) || !isRecord(data.frequencyData)) throw new CommandExecutionError('Nowcoder detail returned malformed post data');
    const isContent = target.post_type === 'content';
    const expectedEntityType = isContent ? CONTENT_ENTITY_TYPE : MOMENT_TYPE;
    if (data.entityType !== expectedEntityType) throw new CommandExecutionError('Nowcoder detail returned a mismatched post entity type');

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass a plain numeric content ID (e.g., '1234567') for discuss posts.
  2. Pass a 32-character hex moment UUID, or a full URL starting with https://www.nowcoder.com/.
  3. If pasting a URL, ensure it includes the https:// scheme — bare 'www.nowcoder.com/...' will not parse.
  4. Quote the argument in your shell so special characters (?, &) are not stripped.

Example fix

// before
nowcoder detail www.nowcoder.com/discuss/1234567
// after
nowcoder detail https://www.nowcoder.com/discuss/1234567
Defensive patterns

Strategy: validation

Validate before calling

const NUMERIC = /^[1-9]\d*$/;
const UUID = /^[0-9a-f]{32}$/i;
function isValidTarget(raw) {
    const v = typeof raw === 'string' ? raw.trim() : '';
    if (NUMERIC.test(v) || UUID.test(v)) return true;
    try { new URL(v); return v.startsWith('https://www.nowcoder.com/') || v.startsWith('https://nowcoder.com/'); }
    catch { return false; }
}

Type guard

function isNowcoderTarget(raw) { const v = typeof raw === 'string' ? raw.trim() : ''; return /^[1-9]\d*$/.test(v) || /^[0-9a-f]{32}$/i.test(v); }

Try / catch

try {
    target = parseNowcoderPostTarget(raw);
} catch (error) {
    if (error instanceof ArgumentError) {
        console.error('Pass a numeric content ID, 32-hex moment UUID, or full https://www.nowcoder.com URL');
        process.exitCode = 2;
    } else throw error;
}

Prevention

When it happens

Trigger: Calling parseNowcoderPostTarget (via the 'nowcoder detail' command target) with a string that is not numeric, not a 32-char hex UUID, and not URL-parseable — e.g., 'abc', 'nowcoder.com/discuss/123' without scheme (actually parses as relative and fails new URL), an empty-ish string with only whitespace, or a non-string coerced to ''.

Common situations: Users pasting a bare domain-less URL like 'www.nowcoder.com/discuss/123456' without https://; shell quoting stripping characters from a URL; typos in a hand-typed post id; passing an int instead of a string so it fails both patterns.

Related errors


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