{"record":{"id":"80f3c6b441cc5beb","repo":"jackwener/OpenCLI","slug":"could-not-find-the-main-post-for-topic-id","errorCode":null,"errorMessage":"Could not find the main post for topic ${id}.","messagePattern":"Could not find the main post for topic (.+?)\\.","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"error","filePath":"clis/linux-do/topic-content.js","lineNumber":64,"sourceCode":"            const needsQuote = /[#{}[\\],&*?|>!%@`'\"]/.test(value) || /: /.test(value) || /:$/.test(value) || value.includes('\\n');\n            frontMatterLines.push(`${key}: ${needsQuote ? `'${value.replace(/'/g, \"''\")}'` : value}`);\n        }\n    }\n    const frontMatter = frontMatterLines.join('\\n');\n    return [\n        frontMatter ? `---\\n${frontMatter}\\n---` : '',\n        params.body.trim(),\n    ].filter(Boolean).join('\\n\\n').trim();\n}\nfunction extractTopicContent(payload, id) {\n    const topic = normalizeTopicPayload(payload);\n    if (!topic) {\n        throw new CommandExecutionError('linux.do returned an unexpected topic payload');\n    }\n    const posts = topic.post_stream?.posts ?? [];\n    const mainPost = posts.find((post) => post.post_number === 1);\n    if (!mainPost) {\n        throw new EmptyResultError('linux-do/topic-content', `Could not find the main post for topic ${id}.`);\n    }\n    const body = typeof mainPost.raw === 'string' && mainPost.raw.trim()\n        ? mainPost.raw.trim()\n        : htmlToMarkdown(mainPost.cooked ?? '');\n    if (!body) {\n        throw new EmptyResultError('linux-do/topic-content', `Topic ${id} does not contain a readable main post body.`);\n    }\n    return {\n        content: buildTopicMarkdownDocument({\n            title: topic.title?.trim() ?? '',\n            author: mainPost.username?.trim() ?? '',\n            likes: typeof mainPost.like_count === 'number' ? mainPost.like_count : undefined,\n            createdAt: toLocalTime(mainPost.created_at ?? ''),\n            url: `${LINUX_DO_HOME}/t/${id}`,\n            body,\n        }),\n    };\n}","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/linux-do/topic-content.js#L46-L82","documentation":"After normalizing the topic, extractTopicContent looks for the post with post_number === 1 (the main/OP post) in topic.post_stream.posts. If it is absent the command cannot render the document, so it throws an EmptyResultError naming the topic ID.","triggerScenarios":"A fetched topic whose post_stream.posts contains no post with post_number 1 — e.g. a truncated post stream from the API, a topic whose first post was deleted, or a partially fetched payload.","commonSituations":"Deleted first post by moderators; topics fetched with a chunked stream API where only later posts were loaded; sites returning summarized post lists; bot/anti-scrape responses missing the OP.","solutions":["Refetch the topic with the full post stream endpoint (`/t/<id>.json?print=true` or with post_ids for post 1).","Verify the topic's first post still exists in the linux.do web UI.","Retry with a signed-in session to get the complete stream.","Fall back to rendering whatever posts are available instead of requiring post 1."],"exampleFix":"// before\nconst payload = await fetchTopicPayload(page, id);\nreturn [extractTopicContent(payload, id)];\n// after\nconst payload = await fetchTopicPayload(page, id);\nif (!payload?.post_stream?.posts?.some((p) => p.post_number === 1)) {\n  console.error(`Topic ${id} is missing its first post; skipping.`);\n  return [];\n}\nreturn [extractTopicContent(payload, id)];","handlingStrategy":"type-guard","validationCode":"if (!payload?.post_stream?.posts?.some((p) => p.post_number === 1)) {\n  throw new Error(`Topic ${id} has no first post`);\n}","typeGuard":"const hasMainPost = (p) =>\n  Array.isArray(p?.post_stream?.posts) && p.post_stream.posts.some((x) => x.post_number === 1);","tryCatchPattern":"try {\n  return extractTopicContent(payload, id);\n} catch (e) {\n  if (e instanceof EmptyResultError && /main post/.test(e.message)) {\n    console.error(`Skipping topic ${id}: first post missing.`);\n    return null;\n  } else throw e;\n}","preventionTips":["Fetch the full post stream for each topic","Skip topics whose OP was deleted","Handle stream-chunked Discourse topics"],"tags":["discourse","empty-result","payload-parsing"],"backgroundTag":"missing-required-field","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}