{"record":{"id":"0b5177779df04433","repo":"jackwener/OpenCLI","slug":"nowcoder-detail-returned-a-different-post-identity","errorCode":null,"errorMessage":"Nowcoder detail returned a different post identity","messagePattern":"Nowcoder detail returned a different post identity","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/nowcoder/posts.js","lineNumber":209,"sourceCode":"        || (host !== 'nowcoder.com' && host !== 'www.nowcoder.com')) {\n        throw new ArgumentError('nowcoder detail only accepts canonical https://www.nowcoder.com post URLs');\n    }\n    const content = url.pathname.match(/^\\/discuss\\/([1-9]\\d*)\\/?$/);\n    if (content) return { post_type: 'content', value: content[1] };\n    const moment = url.pathname.match(/^\\/feed\\/main\\/detail\\/([0-9a-f]{32})\\/?$/i);\n    if (moment) return { post_type: 'moment', value: moment[1].toLowerCase() };\n    throw new ArgumentError('Unsupported Nowcoder URL; expected /discuss/<content-id> or /feed/main/detail/<moment-uuid>');\n}\n\nexport function projectNowcoderDetail(data, target) {\n    if (!isRecord(data) || !isRecord(data.frequencyData)) throw new CommandExecutionError('Nowcoder detail returned malformed post data');\n    const isContent = target.post_type === 'content';\n    const expectedEntityType = isContent ? CONTENT_ENTITY_TYPE : MOMENT_TYPE;\n    if (data.entityType !== expectedEntityType) throw new CommandExecutionError('Nowcoder detail returned a mismatched post entity type');\n    const uuid = requiredUuid(data.uuid, `${target.post_type} uuid`);\n    const entityId = requiredId(data.entityId, `${target.post_type} entity id`);\n    const id = isContent ? requiredId(data.id, 'content id') : uuid;\n    if (isContent ? id !== target.value : uuid !== target.value) throw new CommandExecutionError('Nowcoder detail returned a different post identity');\n    if (!isContent && entityId !== requiredId(data.id, 'moment id')) throw new CommandExecutionError('Nowcoder detail returned mismatched moment entity ids');\n    const expectedAuthorId = isContent ? data.authorId : data.userId;\n    const body = cleanBody(isContent ? data.richText : data.content, `${target.post_type} detail body`);\n    return {\n        post_type: target.post_type,\n        id,\n        uuid,\n        entity_id: entityId,\n        url: isContent\n            ? `https://www.nowcoder.com/discuss/${id}`\n            : `https://www.nowcoder.com/feed/main/detail/${uuid}`,\n        title: optionalText(data.title, `${target.post_type} title`) || '(untitled)',\n        ...authorFields(data.userBrief, expectedAuthorId, target.post_type),\n        content: body,\n        likes: metric(data.frequencyData, 'likeCnt'),\n        comments: metric(data.frequencyData, 'commentCnt'),\n        views: metric(data.frequencyData, 'viewCnt'),\n        time: isoTime(isContent ? data.createTime : data.createdAt, `${target.post_type} timestamp`),","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/nowcoder/posts.js#L191-L227","documentation":"After projecting the detail, projectNowcoderDetail verifies that the returned post's identity matches what you asked for: for content targets the API's id must equal the requested content ID; for moment targets the API's uuid must equal the requested UUID. If Nowcoder's API returns data for a different post than requested (redirect, stale cache, alias resolution), the library throws this CommandExecutionError instead of showing wrong data.","triggerScenarios":"Requesting /discuss/<id> but the API returns a record whose id differs from <id> (e.g. the ID was redirected/merged to another post), or requesting a moment UUID that the API resolves to a different uuid in the response.","commonSituations":"Deleted posts being aliased to other content; cached/stale CDN responses; typos in the ID that happen to resolve to another valid post; Nowcoder server-side redirects on merged or moderated posts.","solutions":["Re-check the content ID / moment UUID for typos and confirm it matches the post you want in the browser.","Clear any cache/CDN layer between you and the API, or retry to rule out stale responses.","If the post was deleted or merged, find and use the new canonical ID/UUID.","If this occurs consistently for a valid ID, report it — the identity check may need to accommodate server-side ID migration."],"exampleFix":"// before\nnowcoder detail 70123457  // typo'd id resolves to another post's record\n// after\nnowcoder detail 70123456  // id copied from the post's canonical URL","handlingStrategy":"validation","validationCode":"// verify the canonical URL actually resolves to this exact ID before fetching\nconst canonical = `https://www.nowcoder.com/discuss/${id}`;\n// confirm canonical URL matches the post you intend before invoking the CLI","typeGuard":null,"tryCatchPattern":"try {\n  const post = await nowcoderDetail(id);\n} catch (err) {\n  if (err instanceof CommandExecutionError && /different post identity/.test(err.message)) {\n    console.error(`API returned a different post for ${id}; it may be deleted/merged. Re-fetch the canonical URL.`);\n  } else throw err;\n}","preventionTips":["Copy IDs from the canonical post URL, not from search results or caches.","Watch for deleted/merged posts — identity mismatches usually mean the ID no longer resolves to itself.","Retry once on failure; persistent mismatches indicate the ID is stale."],"tags":["api-response","data-integrity","consistency-check"],"backgroundTag":"api-identity-mismatch","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}