jackwener/OpenCLI · error · ArgumentError
xiaohongshu/delete-note: note-id must be a 24-character Xiao
Error message
xiaohongshu/delete-note: note-id must be a 24-character Xiaohongshu note ID or an exact Xiaohongshu note URL
What it means
normalizeNoteId accepts either a 24-hex-character note ID (NOTE_ID_RE = /^[0-9a-f]{24}$/i) or an https URL; a non-empty input that is neither format fails here with an ArgumentError, before any URL parsing is attempted.
Source
Thrown at clis/xiaohongshu/delete-note.js:65
return result;
}
function isXiaohongshuHost(hostname) {
const host = String(hostname || '').toLowerCase();
return host === 'xiaohongshu.com' || host.endsWith('.xiaohongshu.com');
}
function isSupportedQueryNoteUrl(url) {
return url.hostname.toLowerCase() === 'creator.xiaohongshu.com'
&& url.pathname.replace(/\/+$/, '') === '/statistics/note-detail';
}
function normalizeNoteId(input) {
const raw = String(input ?? '').trim();
if (!raw) {
throw new ArgumentError('xiaohongshu/delete-note: note-id cannot be empty');
}
if (NOTE_ID_RE.test(raw))
return raw.toLowerCase();
if (!/^https:\/\//i.test(raw)) {
throw new ArgumentError('xiaohongshu/delete-note: note-id must be a 24-character Xiaohongshu note ID or an exact Xiaohongshu note URL');
}
let url;
try {
url = new URL(raw);
}
catch {
throw new ArgumentError('xiaohongshu/delete-note: invalid note URL');
}
if (url.protocol !== 'https:' || url.username || url.password || url.port || !isXiaohongshuHost(url.hostname)) {
throw new ArgumentError('xiaohongshu/delete-note: note URL must be an exact https://*.xiaohongshu.com URL');
}
const queryId = url.searchParams.get('noteId') || url.searchParams.get('note_id');
if (queryId && NOTE_ID_RE.test(queryId) && isSupportedQueryNoteUrl(url))
return queryId.toLowerCase();
const pathMatch = url.pathname.match(/^\/(?:explore|note|search_result|discovery\/item)\/([0-9a-f]{24})\/?$/i)
|| url.pathname.match(/^\/user\/profile\/[^/?#]+\/([0-9a-f]{24})\/?$/i);
if (pathMatch)
return pathMatch[1].toLowerCase();View on GitHub (pinned to 49907e53dc)
Solutions
- Provide the full 24-character hex note ID, or the complete https:// note URL
- Extract the 24-hex ID from the note page URL (the path segment after /explore/ or /discovery/item/)
- Add the https:// scheme if you have a bare xiaohongshu.com link
- Validate the format before calling: /^[0-9a-f]{24}$/i.test(id) || id.startsWith('https://')
Example fix
// before
await deleteNote({ noteId: '665f1a2b' }); // too short, not a valid ID
// after
await deleteNote({ noteId: 'https://www.xiaohongshu.com/explore/665f1a2b000000001234abcd' });
// or the bare ID: '665f1a2b000000001234abcd' Defensive patterns
Strategy: validation
Validate before calling
const NOTE_ID_RE = /^[0-9a-f]{24}$/i;
function isValidNoteId(v) {
const s = String(v ?? '').trim();
if (NOTE_ID_RE.test(s)) return true;
if (!s.startsWith('https://')) return false;
try { new URL(s); return true; } catch { return false; }
}
if (!isValidNoteId(noteId)) throw new Error('note-id must be 24-hex ID or exact https note URL'); Type guard
function isWellFormedNoteId(v) { return typeof v === 'string' && (/^[0-9a-f]{24}$/i.test(v.trim()) || /^https:\/\//.test(v.trim())); } Try / catch
try {
await deleteNote({ noteId });
} catch (e) {
if (e instanceof ArgumentError && /24-character/.test(e.message)) {
// normalize input: extract the 24-hex ID from the URL or add https:// and retry
} else { throw e; }
} Prevention
- Extract the 24-hex ID from the /explore/ or /discovery/item/ URL path when in doubt
- Never pass partial IDs or scheme-less links; keep the https:// prefix
- Centralize a single note-id normalizer/validator in your tooling and reuse it
When it happens
Trigger: Passing a note-id that is not 24 hex characters and does not start with `https://` — e.g. a short ID, an internal numeric ID, a URL with `http://` instead of https, or a share link with the scheme stripped.
Common situations: Copy-pasting only part of a note URL; using the numeric display ID instead of the 24-char hex ID; stripping the https:// prefix; passing a mobile-app share text fragment.
Related errors
- ${label} must be a non-negative integer, got ${JSON.stringif
- limit must be a positive integer
- bilibili comment ${label} must be a positive integer
- bilibili comment message cannot be empty
- bilibili unfollow target cannot be empty
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/b6cfc05c46077ad5.
Report an issue: GitHub.