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
- Pass only the numeric id, e.g. normalizeDoubanSubjectId('1292052')
- If you have a URL, extract the digits first: url.match(/subject\/(\d+)/)[1]
- 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
- Extract the numeric id from URLs with /subject\/(\d+)/ before calling
- Trim inputs and reject empty values at the CLI boundary
- Keep subject ids as plain digit strings in stored config
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
- '${rawInput}' does not look like a dongchedi series id (a nu
- Unknown 12306 station telecode "${trimmed}"
- Unknown 12306 station "${trimmed}"
- date must be YYYY-MM-DD, got "${value}"
- date "${value}" is not a real calendar date
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/310e26a37a8e522f.
Report an issue: GitHub.