{"record":{"id":"b6cfc05c46077ad5","repo":"jackwener/OpenCLI","slug":"xiaohongshu-delete-note-note-id-must-be-a-24-char","errorCode":null,"errorMessage":"xiaohongshu/delete-note: note-id must be a 24-character Xiaohongshu note ID or an exact Xiaohongshu note URL","messagePattern":"xiaohongshu/delete-note: note-id must be a 24-character Xiaohongshu note ID or an exact Xiaohongshu note URL","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/xiaohongshu/delete-note.js","lineNumber":65,"sourceCode":"    return result;\n}\nfunction isXiaohongshuHost(hostname) {\n    const host = String(hostname || '').toLowerCase();\n    return host === 'xiaohongshu.com' || host.endsWith('.xiaohongshu.com');\n}\nfunction isSupportedQueryNoteUrl(url) {\n    return url.hostname.toLowerCase() === 'creator.xiaohongshu.com'\n        && url.pathname.replace(/\\/+$/, '') === '/statistics/note-detail';\n}\nfunction normalizeNoteId(input) {\n    const raw = String(input ?? '').trim();\n    if (!raw) {\n        throw new ArgumentError('xiaohongshu/delete-note: note-id cannot be empty');\n    }\n    if (NOTE_ID_RE.test(raw))\n        return raw.toLowerCase();\n    if (!/^https:\\/\\//i.test(raw)) {\n        throw new ArgumentError('xiaohongshu/delete-note: note-id must be a 24-character Xiaohongshu note ID or an exact Xiaohongshu note URL');\n    }\n    let url;\n    try {\n        url = new URL(raw);\n    }\n    catch {\n        throw new ArgumentError('xiaohongshu/delete-note: invalid note URL');\n    }\n    if (url.protocol !== 'https:' || url.username || url.password || url.port || !isXiaohongshuHost(url.hostname)) {\n        throw new ArgumentError('xiaohongshu/delete-note: note URL must be an exact https://*.xiaohongshu.com URL');\n    }\n    const queryId = url.searchParams.get('noteId') || url.searchParams.get('note_id');\n    if (queryId && NOTE_ID_RE.test(queryId) && isSupportedQueryNoteUrl(url))\n        return queryId.toLowerCase();\n    const pathMatch = url.pathname.match(/^\\/(?:explore|note|search_result|discovery\\/item)\\/([0-9a-f]{24})\\/?$/i)\n        || url.pathname.match(/^\\/user\\/profile\\/[^/?#]+\\/([0-9a-f]{24})\\/?$/i);\n    if (pathMatch)\n        return pathMatch[1].toLowerCase();","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xiaohongshu/delete-note.js#L47-L83","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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://')"],"exampleFix":"// before\nawait deleteNote({ noteId: '665f1a2b' }); // too short, not a valid ID\n// after\nawait deleteNote({ noteId: 'https://www.xiaohongshu.com/explore/665f1a2b000000001234abcd' });\n// or the bare ID: '665f1a2b000000001234abcd'","handlingStrategy":"validation","validationCode":"const NOTE_ID_RE = /^[0-9a-f]{24}$/i;\nfunction isValidNoteId(v) {\n  const s = String(v ?? '').trim();\n  if (NOTE_ID_RE.test(s)) return true;\n  if (!s.startsWith('https://')) return false;\n  try { new URL(s); return true; } catch { return false; }\n}\nif (!isValidNoteId(noteId)) throw new Error('note-id must be 24-hex ID or exact https note URL');","typeGuard":"function isWellFormedNoteId(v) { return typeof v === 'string' && (/^[0-9a-f]{24}$/i.test(v.trim()) || /^https:\\/\\//.test(v.trim())); }","tryCatchPattern":"try {\n  await deleteNote({ noteId });\n} catch (e) {\n  if (e instanceof ArgumentError && /24-character/.test(e.message)) {\n    // normalize input: extract the 24-hex ID from the URL or add https:// and retry\n  } else { throw e; }\n}","preventionTips":["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"],"tags":["argument-validation","input-validation","format-mismatch","cli"],"backgroundTag":"invalid-id-format","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}