jackwener/OpenCLI · error · CommandExecutionError

Zhihu answer comments referenced missing parent ${cursor}

Error message

Zhihu answer comments referenced missing parent ${cursor}

What it means

resolveDepths walks each reply's parent chain up to the root comment to compute thread depth. If the chain reaches a comment id that is not present in childrenById (i.e. the parent was never fetched or was filtered out), the graph is incomplete, so it throws. This guards against producing rows with wrong or infinite depth values.

Source

Thrown at clis/zhihu/answer-comments-helpers.js:208

        }
        repliesByRoot.set(id, children);
    }
    return repliesByRoot;
}
function resolveDepths(rootId, childrenById) {
    const depths = new Map();
    for (const childId of childrenById.keys()) {
        if (depths.has(childId)) continue;
        const chain = [];
        const active = new Set();
        let cursor = childId;
        let depth = 0;
        while (cursor !== rootId && !depths.has(cursor)) {
            if (active.has(cursor)) throw new CommandExecutionError(`Zhihu answer comments contained a reply cycle at ${cursor}`);
            active.add(cursor);
            chain.push(cursor);
            const node = childrenById.get(cursor);
            if (!node) throw new CommandExecutionError(`Zhihu answer comments referenced missing parent ${cursor}`);
            cursor = node.descriptor.parentId;
        }
        if (cursor !== rootId) depth = depths.get(cursor);
        for (let index = chain.length - 1; index >= 0; index -= 1) depths.set(chain[index], ++depth);
    }
    return depths;
}
function toRow(comment, descriptor, ranks, context) {
    return {
        rank: ranks.rank,
        comment_rank: ranks.commentRank,
        reply_rank: ranks.replyRank,
        depth: ranks.depth,
        id: descriptor.id,
        parent_id: descriptor.parentId,
        author: memberName(comment.author) || 'anonymous',
        reply_to: descriptor.parentId ? memberName(comment.reply_to_author) : '',
        likes: normalizeCount(comment.like_count ?? comment.vote_count),

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify the reply chain: fetch with a larger --replies-limit so intermediate parents are included
  2. Skip (or attach to root) replies whose parent is missing instead of throwing — patch resolveDepths to treat unknown parents as depth 1
  3. Log cursor and the set of fetched ids to identify which parent id is absent, then check whether Zhihu's API omits deleted comments
  4. Retry later — if the parent is temporarily hidden it may reappear

Example fix

// before
const node = childrenById.get(cursor);
if (!node) throw new CommandExecutionError(`Zhihu answer comments referenced missing parent ${cursor}`);
// after
const node = childrenById.get(cursor);
if (!node) { depths.set(cursor, depth + 1); break; } // tolerate deleted/omitted parents
Defensive patterns

Strategy: validation

Validate before calling

const fetchedIds = new Set(Object.keys(childrenById));
for (const node of childrenById.values()) {
  if (node.descriptor.parentId !== rootId && !fetchedIds.has(node.descriptor.parentId)) {
    console.warn('parent not fetched:', node.descriptor.parentId);
  }
}

Type guard

const hasParent = (node) => typeof node?.descriptor?.parentId === 'string' && (node.descriptor.parentId === rootId || childrenById.has(node.descriptor.parentId));

Try / catch

try { depths = resolveDepths(rootId, childrenById); }
catch (err) {
  if (String(err.message).includes('referenced missing parent')) { /* rebuild rows skipping orphaned replies */ }
  else throw err;
}

Prevention

When it happens

Trigger: A reply's descriptor.parentId points to a comment that is not among the fetched replies for that root (parent deleted, hidden by Zhihu, or excluded by the --replies-limit/pagination cut).

Common situations: Zhihu deleted a mid-thread parent comment so children remain but the parent no longer appears in the API response; or replies were truncated by replies-limit while children of deeper nodes were still fetched; or the API returned comments out of order after an A/B change.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/18eed7c09da020e7. Report an issue: GitHub.