jackwener/OpenCLI · error · CommandExecutionError
linux.do returned an unexpected topic payload
Error message
linux.do returned an unexpected topic payload
What it means
extractTopicContent calls normalizeTopicPayload on the fetched topic JSON; if the payload cannot be normalized into a recognizable topic object (null/undefined result), it throws a CommandExecutionError. This guards against feeding malformed or non-topic data into the extraction pipeline.
Source
Thrown at clis/linux-do/topic-content.js:59
if (typeof value === 'number') {
frontMatterLines.push(`${key}: ${value}`);
}
else {
// Quote strings that could be misinterpreted by YAML parsers
const needsQuote = /[#{}[\],&*?|>!%@`'"]/.test(value) || /: /.test(value) || /:$/.test(value) || value.includes('\n');
frontMatterLines.push(`${key}: ${needsQuote ? `'${value.replace(/'/g, "''")}'` : value}`);
}
}
const frontMatter = frontMatterLines.join('\n');
return [
frontMatter ? `---\n${frontMatter}\n---` : '',
params.body.trim(),
].filter(Boolean).join('\n\n').trim();
}
function extractTopicContent(payload, id) {
const topic = normalizeTopicPayload(payload);
if (!topic) {
throw new CommandExecutionError('linux.do returned an unexpected topic payload');
}
const posts = topic.post_stream?.posts ?? [];
const mainPost = posts.find((post) => post.post_number === 1);
if (!mainPost) {
throw new EmptyResultError('linux-do/topic-content', `Could not find the main post for topic ${id}.`);
}
const body = typeof mainPost.raw === 'string' && mainPost.raw.trim()
? mainPost.raw.trim()
: htmlToMarkdown(mainPost.cooked ?? '');
if (!body) {
throw new EmptyResultError('linux-do/topic-content', `Topic ${id} does not contain a readable main post body.`);
}
return {
content: buildTopicMarkdownDocument({
title: topic.title?.trim() ?? '',
author: mainPost.username?.trim() ?? '',
likes: typeof mainPost.like_count === 'number' ? mainPost.like_count : undefined,
createdAt: toLocalTime(mainPost.created_at ?? ''),View on GitHub (pinned to 49907e53dc)
Solutions
- Ensure you are signed in to linux.do in the controlling browser session (`browser sign-in` flow).
- Verify the topic ID exists and is publicly viewable.
- Log the raw payload returned by fetchTopicPayload to inspect what linux.do actually sent.
- Retry later — the site may be serving an interstitial or outage.
Example fix
// before
const payload = await fetchTopicPayload(page, 12345);
const content = extractTopicContent(payload, 12345);
// after
const payload = await fetchTopicPayload(page, 12345);
if (!payload?.id) {
throw new Error('Topic payload unusable — check linux.do session in browser');
}
const content = extractTopicContent(payload, 12345); Defensive patterns
Strategy: type-guard
Validate before calling
if (!payload || typeof payload !== 'object' || !payload.id) {
throw new Error('Topic payload is not a valid topic object');
} Type guard
const isTopicPayload = (p) => Boolean(p && typeof p === 'object' && typeof p.id === 'number' && Array.isArray(p.post_stream?.posts));
Try / catch
try {
return extractTopicContent(payload, id);
} catch (e) {
if (e instanceof CommandExecutionError && /unexpected topic payload/.test(e.message)) {
console.error('linux.do did not return topic JSON — check your browser session.');
} else throw e;
} Prevention
- Keep a signed-in linux.do browser session
- Verify topics exist before batch processing
- Log raw payloads when parsing fails
When it happens
Trigger: fetchTopicPayload returns a body that, after normalization, is not a topic object — e.g. the JSON endpoint returns an HTML login page, an error object, a deleted/hidden topic response, or null data.
Common situations: Expired or missing browser session so linux.do returns a login/error page; deleted or restricted topic; scraping/captcha interstitial; linux.do API schema change.
Related errors
- HTTP ' + res.status + ' - make sure you are logged in to Ins
- Could not find the main post for topic ${id}.
- linux.do requires an active signed-in browser session
- linux.do request failed: HTTP ${result.status ?? 'unknown'}
- Please verify your linux.do session is still valid
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/8b5d7e62962b12dd.
Report an issue: GitHub.