{"record":{"id":"3edef098ba95a313","repo":"jackwener/OpenCLI","slug":"pixiv-bookmark-item-returned-malformed-creation-da","errorCode":null,"errorMessage":"Pixiv bookmark item returned malformed creation date","messagePattern":"Pixiv bookmark item returned malformed creation date","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/pixiv/bookmark-utils.js","lineNumber":23,"sourceCode":"  normalizePixivPositiveInteger,\n  pixivFetch,\n  requirePixivId,\n  requirePixivPayloadObject,\n  requirePixivString,\n} from './utils.js';\n\nexport function normalizeBookmarkType(value) {\n  const type = String(value ?? 'illust').trim();\n  if (type !== 'illust' && type !== 'novel') {\n    throw new ArgumentError(`Invalid bookmark type: ${type}. Expected \"illust\" or \"novel\".`);\n  }\n  return type;\n}\n\nexport function dateOnly(value) {\n  if (value == null || value === '') return '';\n  if (typeof value !== 'string' || !/^\\d{4}-\\d{2}-\\d{2}(?:T|$)/.test(value)) {\n    throw new CommandExecutionError('Pixiv bookmark item returned malformed creation date');\n  }\n  return value.split('T')[0];\n}\n\nexport function tagsToString(tags) {\n  if (tags == null) return '';\n  const values = Array.isArray(tags) ? tags : (Array.isArray(tags?.tags) ? tags.tags : null);\n  if (!values) {\n    throw new CommandExecutionError('Pixiv item returned malformed tags payload');\n  }\n  return values.map((entry) => {\n    const value = typeof entry === 'string' ? entry : entry?.tag;\n    if (typeof value !== 'string' || !value.trim()) {\n      throw new CommandExecutionError('Pixiv item returned malformed tag');\n    }\n    return value.trim();\n  }).join(', ');\n}","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/pixiv/bookmark-utils.js#L5-L41","documentation":"dateOnly normalizes a Pixiv bookmark item's creation date into a YYYY-MM-DD string. It throws CommandExecutionError when the value is a non-string or does not start with an ISO date (YYYY-MM-DD, optionally followed by 'T'), meaning the API response item was structurally unexpected.","triggerScenarios":"Parsing a bookmark list item whose created date field is missing, null-like values that pass the empty check (e.g. whitespace string), numeric timestamps, or API responses in an unexpected date format (e.g. '2024/01/02' or epoch millis).","commonSituations":"Pixiv API schema changes, partially failed API responses, proxy/mirror endpoints returning reformatted dates, items fetched from unofficial or cached endpoints.","solutions":["Check the raw API response item and confirm the created date field is an ISO 'YYYY-MM-DD...' string","Update the library / re-fetch the item in case the response was truncated or stale","If using a custom endpoint or proxy, verify it does not rewrite date formats; pre-normalize dates to ISO"],"exampleFix":"// before\nitem.createdAt = 1735732800000\n// after\nitem.createdAt = '2024-01-02T00:00:00+09:00'","handlingStrategy":"type-guard","validationCode":"function hasIsoDate(item) { return typeof item?.createdAt === 'string' && /^\\d{4}-\\d{2}-\\d{2}(?:T|$)/.test(item.createdAt); }\nif (!bookmarkItems.every(hasIsoDate)) throw new Error('Response contains items with non-ISO createdAt');","typeGuard":"function isIsoDateString(v) { return typeof v === 'string' && /^\\d{4}-\\d{2}-\\d{2}(?:T|$)/.test(v); }","tryCatchPattern":"try { const rows = items.map(bookmarkRow); /* ... */ } catch (err) { if (err.message.includes('malformed creation date')) { console.error('Pixiv API returned an item with an invalid date; re-fetching...'); } else throw err; }","preventionTips":["Validate API response schemas (zod/ajv) before mapping rows","Prefer official endpoints over proxies that may reformat dates","Log the raw offending item when this error occurs to spot schema drift early"],"tags":["pixiv","data-parsing","date-validation","api-response"],"backgroundTag":"malformed-api-response","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}