{"record":{"id":"aa70f1932931071a","repo":"TryGhost/Ghost","slug":"you-cannot-destroy-comments","errorCode":null,"errorMessage":"You cannot destroy comments.","messagePattern":"You cannot destroy comments\\.","errorType":"exception","errorClass":"MethodNotAllowedError","httpStatus":405,"severity":"error","filePath":"ghost/core/core/server/services/comments/comments-controller.js","lineNumber":329,"sourceCode":"                data.html,\n                frame.options\n            );\n        } else {\n            result = await this.service.commentOnPost(\n                data.post_id,\n                frame.options.context.member.id,\n                data.html,\n                frame.options\n            );\n        }\n\n        this.setCacheInvalidationHeaders(result, frame);\n\n        return result;\n    }\n\n    async destroy() {\n        throw new MethodNotAllowedError({\n            message: tpl(messages.cannotDestroyComments)\n        });\n    }\n\n    async count(frame) {\n        if (!frame?.options?.ids) {\n            return await this.stats.getAllCounts();\n        }\n\n        const ids = frame?.options?.ids.split(',');\n\n        return await this.stats.getCountsByPost(ids);\n    }\n\n    /**\n     * @param {Frame} frame\n     */\n    async like(frame) {","sourceCodeStart":311,"sourceCodeEnd":347,"githubUrl":"https://github.com/TryGhost/Ghost/blob/47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe/ghost/core/core/server/services/comments/comments-controller.js#L311-L347","documentation":"A MethodNotAllowedError thrown unconditionally by `destroy()` in the comments controller. Ghost's public comments API does not permit deleting comments through this endpoint — the method body simply throws regardless of input. It is a hard contract, not a conditional check, so no payload will succeed.","triggerScenarios":"Sending a `DELETE` request to the public comments resource (e.g. `DELETE /api/member/comments/{id}` or the equivalent admin/comments route). Any such request hits this controller method and is rejected.","commonSituations":"A client SDK defaults to DELETE for resource removal and a developer assumed comments support it; a frontend wired a delete button to the comments endpoint; confusion between the public comments API (no delete) and a moderation/admin workflow.","solutions":["Do not call DELETE on comments — this operation is intentionally unsupported in the public API.","If moderation removal is required, use the admin moderation tools or mark the comment as reported/hidden per the supported flows.","Remove or disable the delete UI affordance for comments in the client.","Handle `405 Method Not Allowed` gracefully and inform the user comments cannot be deleted."],"exampleFix":"// before\nawait api.comments.destroy({id}); // -> 405\n\n// after: use the supported moderation action instead (e.g. report)\nawait api.comments.report({id, reason});\n// or hide the delete button in the UI","handlingStrategy":"type-guard","validationCode":"// There is no payload that succeeds; guard the call site\nfunction assertCommentsDestroyAllowed() {\n  throw new Error('DELETE is not supported on comments; remove the call');\n}","typeGuard":"const supportsCommentDestroy = false; // hard contract — never call destroy()","tryCatchPattern":"try {\n  await api.comments.destroy({id});\n} catch (err) {\n  if (err.type === 'MethodNotAllowedError') informUser('Comments cannot be deleted');\n  else throw err;\n}","preventionTips":["Never wire a delete affordance to the comments endpoint.","Use supported moderation/report flows instead.","Document in your client SDK that comments have no DELETE."],"tags":["comments","method-not-allowed","api-contract","public-api"],"backgroundTag":null,"analyzedSha":"47d8b0e2ad2fd4757d3bc45f46c3ac165ff8a1fe","analyzedAt":"2026-08-13T01:25:26.651Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}