{"record":{"id":"a667b838ec7623e2","repo":"toeverything/AFFiNE","slug":"comment-not-found-a667b8","errorCode":"comment_not_found","errorMessage":"Comment not found.","messagePattern":"Comment not found\\.","errorType":"exception","errorClass":"CommentNotFound","httpStatus":404,"severity":"error","filePath":"packages/backend/server/src/models/comment.ts","lineNumber":285,"sourceCode":"\n    return changes;\n  }\n\n  // #endregion\n\n  // #region Reply\n\n  /**\n   * Reply to a comment\n   * @param input - The reply create input\n   * @returns The created reply\n   */\n  async createReply(input: ReplyCreate) {\n    const data = ReplyCreateSchema.parse(input);\n    // find comment\n    const comment = await this.get(data.commentId);\n    if (!comment) {\n      throw new CommentNotFound();\n    }\n\n    return (await this.db.reply.create({\n      data: {\n        ...data,\n        workspaceId: comment.workspaceId,\n        docId: comment.docId,\n      },\n    })) as Reply;\n  }\n\n  async getReply(id: string) {\n    return (await this.db.reply.findUnique({\n      where: { id, deletedAt: null },\n    })) as Reply | null;\n  }\n\n  async listReplies(workspaceId: string, docId: string, commentId: string) {","sourceCodeStart":267,"sourceCodeEnd":303,"githubUrl":"https://github.com/toeverything/AFFiNE/blob/b4c8548c09da21b2898443559a5b846f0ccf5dd8/packages/backend/server/src/models/comment.ts#L267-L303","documentation":"Thrown by CommentModel.createReply when this.get(data.commentId) returns null — the comment being replied to does not exist (deleted or unknown id). Replies are anchored to their parent comment's workspaceId/docId, which is why the parent must resolve first.","triggerScenarios":"Calling the createReply mutation/API with a commentId that was deleted, a doc comment that disappeared when its page was removed, or a malformed id.","commonSituations":"Replying from a stale open editor after another user deleted the comment; page deleted or moved to trash taking its comments along; id typo from API consumers.","solutions":["Refresh the comment list for the doc and reply to an existing comment id from that fresh list.","If the parent comment was deleted, start a new comment instead of a reply.","For API callers, validate the commentId exists (GET the comment) before posting the reply."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Confirm the parent comment still exists before posting the reply\nconst comment = await gql.request(GET_COMMENT, { id: commentId });\nif (!comment.comment) {\n  refreshCommentList(); // parent is gone — reload instead of replying\n} else {\n  await gql.request(CREATE_REPLY, { input: { commentId, body } });\n}","typeGuard":"const isCommentNotFound = (e: unknown): boolean =>\n  getGraphqlErrorCode(e) === 'comment_not_found';","tryCatchPattern":"try {\n  await createReply({ commentId, body });\n} catch (e) {\n  if (isCommentNotFound(e)) {\n    refreshCommentList(); // drop the stale reply box\n  }\n}","preventionTips":["Refresh the comment list when the editor regains focus so deleted parents disappear before reply submission.","For API consumers, resolve commentId to an existing comment before posting the reply."],"tags":["comment","reply","not-found","graphql","collaboration"],"backgroundTag":"comment-not-found","analyzedSha":"b4c8548c09da21b2898443559a5b846f0ccf5dd8","analyzedAt":"2026-08-18T21:16:52.546Z","contentChangedAt":"2026-08-18T21:16:52.546Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}