jackwener/OpenCLI · error · ArgumentError

Invalid Douban subject ID: ${subjectId}

Error message

Invalid Douban subject ID: ${subjectId}

What it means

normalizeDoubanSubjectId requires the subject id to be a pure digit string. It throws ArgumentError for anything else, since douban subject ids are numeric and downstream URLs are built from the normalized value.

Source

Thrown at clis/douban/utils.js:128

            if (attempt >= attempts - 1 || !isDetachedPageError(error)) {
                throw error;
            }
        }
    }
    throw lastError;
}
function buildDoubanSearchUrl(type, keyword) {
    const url = new URL(`https://search.douban.com/${encodeURIComponent(type)}/subject_search`);
    url.searchParams.set('search_text', String(keyword || ''));
    if (String(type || '').trim() === 'book') {
        url.searchParams.set('cat', '1001');
    }
    return url.toString();
}
export function normalizeDoubanSubjectId(subjectId) {
    const normalized = String(subjectId || '').trim();
    if (!/^\d+$/.test(normalized)) {
        throw new ArgumentError(`Invalid Douban subject ID: ${subjectId}`);
    }
    return normalized;
}
export function promoteDoubanPhotoUrl(url, size = 'l') {
    const normalized = String(url || '').trim();
    if (!normalized)
        return '';
    if (/^[a-z]+:/i.test(normalized) && !/^https?:/i.test(normalized))
        return '';
    return normalized.replace(/\/view\/photo\/[^/]+\/public\//, `/view/photo/${size}/public/`);
}
export function resolveDoubanPhotoAssetUrl(candidates, baseUrl = '') {
    for (const candidate of candidates) {
        const normalized = String(candidate || '').trim();
        if (!normalized)
            continue;
        let resolved = normalized;
        try {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass only the numeric id, e.g. normalizeDoubanSubjectId('1292052')
  2. If you have a URL, extract the digits first: url.match(/subject\/(\d+)/)[1]
  3. Trim surrounding whitespace and confirm the value is not empty

Example fix

// before
normalizeDoubanSubjectId('https://movie.douban.com/subject/1292052/');
// after
const m = url.match(/subject\/(\d+)/);
normalizeDoubanSubjectId(m[1]);
Defensive patterns

Strategy: validation

Validate before calling

const s = String(subjectId ?? '').trim();
if (!/^\d+$/.test(s)) throw new Error(`Subject id must be digits; got ${subjectId}`);

Type guard

function isDoubanSubjectId(v) { return /^\d+$/.test(String(v ?? '').trim()); }

Try / catch

try { await doubanSubject(subjectId); } catch (e) { if (e.name === 'ArgumentError') { const m = String(subjectId).match(/subject\/(\d+)/); if (m) return doubanSubject(m[1]); } throw e; }

Prevention

When it happens

Trigger: Passing a full douban URL (e.g. https://movie.douban.com/subject/1292052/) instead of the bare id; an id with whitespace, letters, or a trailing slash; null/undefined/empty input.

Common situations: Copying the whole subject URL from the browser; mixing up douban.com/book/subject/ URL forms; a spreadsheet column containing URLs rather than ids.

Related errors


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