From 9d8c96f01ec69b25eeb5b609bd0fea6b4569da5e Mon Sep 17 00:00:00 2001 From: Vlad Mocanu Date: Thu, 26 Feb 2026 08:39:30 +0200 Subject: [PATCH] fix: handle missing comment payload in Forgejo pull_request_review_comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Forgejo's pull_request_review_comment event does NOT include a top-level `comment` object in the webhook payload. This caused crashes at: - create-initial.ts: context.payload.comment.id (for reply-to-review) - fetcher.ts: context.payload.comment.created_at (for trigger timestamp) Fix: use optional chaining and fall back gracefully — reply-to-review becomes a regular issue comment, trigger timestamp returns undefined. Co-Authored-By: Claude Opus 4.6 --- src/github/data/fetcher.ts | 3 +- .../operations/comments/create-initial.ts | 28 +++++++++++++------ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/github/data/fetcher.ts b/src/github/data/fetcher.ts index 8d0e6eb..2b3d5c6 100644 --- a/src/github/data/fetcher.ts +++ b/src/github/data/fetcher.ts @@ -40,7 +40,8 @@ export function extractTriggerTimestamp( } else if (isPullRequestReviewEvent(context)) { return context.payload.review.submitted_at || undefined; } else if (isPullRequestReviewCommentEvent(context)) { - return context.payload.comment.created_at || undefined; + // Forgejo's pull_request_review_comment payload may lack the `comment` object + return (context.payload as any).comment?.created_at || undefined; } return undefined; diff --git a/src/github/operations/comments/create-initial.ts b/src/github/operations/comments/create-initial.ts index dd678c0..e9d044b 100644 --- a/src/github/operations/comments/create-initial.ts +++ b/src/github/operations/comments/create-initial.ts @@ -77,14 +77,26 @@ export async function createInitialComment( }); } } else if (isPullRequestReviewCommentEvent(context)) { - // Only use createReplyForReviewComment if it's a PR review comment AND we have a comment_id - response = await octokit.rest.pulls.createReplyForReviewComment({ - owner, - repo, - pull_number: context.entityNumber, - comment_id: context.payload.comment.id, - body: initialBody, - }); + // Only use createReplyForReviewComment if we have a comment_id. + // Forgejo's pull_request_review_comment payload lacks the top-level + // `comment` object, so fall back to a regular issue comment there. + const reviewCommentId = (context.payload as any).comment?.id; + if (reviewCommentId) { + response = await octokit.rest.pulls.createReplyForReviewComment({ + owner, + repo, + pull_number: context.entityNumber, + comment_id: reviewCommentId, + body: initialBody, + }); + } else { + response = await octokit.rest.issues.createComment({ + owner, + repo, + issue_number: context.entityNumber, + body: initialBody, + }); + } } else { // For all other cases (issues, issue comments, or missing comment_id) response = await octokit.rest.issues.createComment({