{"record":{"id":"31db747efa9c6c19","repo":"TryGhost/Ghost","slug":"failed-to-fetch-comments","errorCode":null,"errorMessage":"Failed to fetch comments","messagePattern":"Failed to fetch comments","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/comments-ui/src/utils/api.ts","lineNumber":157,"sourceCode":"                    params.set('filter', filter);\n                }\n                params.set('page', page.toString());\n                if (order) {\n                    params.set('order', order);\n                }\n                const url = endpointFor({type: 'members', resource: `comments/post/${postId}`, params: `?${params.toString()}`});\n                const response = makeRequest({\n                    url,\n                    method: 'GET',\n                    headers: {\n                        'Content-Type': 'application/json'\n                    },\n                    credentials: 'same-origin'\n                }).then(function (res) {\n                    if (res.ok) {\n                        return res.json();\n                    } else {\n                        throw new Error('Failed to fetch comments');\n                    }\n                });\n\n                if (!firstCommentCreatedAt) {\n                    response.then((body) => {\n                        const firstComment = body.comments[0];\n                        if (firstComment) {\n                            firstCommentCreatedAt = firstComment.created_at;\n                        }\n                    });\n                }\n\n                return response;\n            },\n            async replies({commentId, afterReplyId, limit, page}: {commentId: string; afterReplyId?: string; limit?: number | 'all'; page?: number}) {\n                if (limit === 'all') {\n                    // Paginate by page, not an `id:>` cursor: replies are ordered by\n                    // created_at, so an id cursor can re-fetch or skip replies (BER-3706).","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/TryGhost/Ghost/blob/47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe/apps/comments-ui/src/utils/api.ts#L139-L175","documentation":"comments.browse() GETs /members/api/comments/post/{postId} with pagination and filter params to load the comment thread for a post. If the response is not ok, it throws. A side-effect after the response (capturing firstCommentCreatedAt for pagination dedup) only runs on success because it is chained on the resolved promise.","triggerScenarios":"The comments browse GET returns 4xx/5xx. The postId is invalid or the post has comments disabled (404/403), the member session expired (401), the server is overloaded (503), or the request is rate-limited (429). If the request fails, the firstCommentCreatedAt pagination anchor is not set, so subsequent calls have no dedup filter.","commonSituations":"A post with comments disabled by the author returns 404. The member's cookie expired between page load and the comments fetch. A spike in traffic triggers rate limiting. The postId passed does not match any post.","solutions":["Check the Network tab for the comments GET status code.","If 401/403, ensure the member session cookie is present and valid; re-init the member identity.","If 404, confirm the postId is correct and that comments are enabled on that post.","Handle the rejected promise in the UI to show an empty or error state rather than a blank thread."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"function isValidPostId(postId: string | null): boolean {\n  return typeof postId === 'string' && postId.length > 0;\n}","typeGuard":null,"tryCatchPattern":"try {\n  const data = await api.comments.browse({page: 1, postId});\n} catch (e) {\n  if (e instanceof Error && e.message === 'Failed to fetch comments') {\n    // show empty/error state in the comment list\n  }\n}","preventionTips":["Validate postId is a non-empty string before calling browse.","Handle the rejected promise in the UI to show a retry option rather than a blank thread.","If 401, re-establish the member session before allowing the user to retry."],"tags":["network","fetch","comments-ui","comments","pagination"],"backgroundTag":null,"analyzedSha":"47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe","analyzedAt":"2026-08-13T01:25:26.651Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}