{"record":{"id":"d909b2dd7de8500b","repo":"mastra-ai/mastra","slug":"a-review-comment-requires-commitid-path-line-an-d909b2","errorCode":null,"errorMessage":"A review comment requires commitId, path, line, and side unless it is a reply.","messagePattern":"A review comment requires commitId, path, line, and side unless it is a reply\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"mastracode/factory/src/integrations/platform/github/integration.ts","lineNumber":1371,"sourceCode":"  async #listReviewComments(input: ListReviewCommentsInput) {\n    const page = parsePositiveCursor(input.cursor);\n    const result = await this.#client.request<{ comments: GithubReviewComment[] }>(\n      'GET',\n      `${pullRequestPath(input, input.pullRequestId)}/comments?page=${page}&per_page=${PAGE_SIZE}`,\n    );\n    return {\n      comments: result.comments.map(parseReviewComment),\n      nextCursor: result.comments.length === PAGE_SIZE ? String(page + 1) : null,\n    };\n  }\n\n  async #createReviewComment(input: CreateReviewCommentInput) {\n    let body: Record<string, unknown>;\n    if (input.replyToId !== undefined) {\n      body = { body: input.body, replyToId: requirePositiveId(input.replyToId, 'review comment') };\n    } else {\n      if (!input.commitId || !input.path || input.line === undefined || !input.side) {\n        throw new Error('A review comment requires commitId, path, line, and side unless it is a reply.');\n      }\n      body = {\n        body: input.body,\n        commitId: input.commitId,\n        path: input.path,\n        line: input.line,\n        side: input.side.toUpperCase(),\n        startLine: input.startLine,\n        startSide: input.startSide?.toUpperCase(),\n      };\n    }\n    return parseReviewComment(\n      await this.#client.request<GithubReviewComment>(\n        'POST',\n        `${pullRequestPath(input, input.pullRequestId)}/comments`,\n        body,\n        { actingUserId: input.actingUserId },\n      ),","sourceCodeStart":1353,"sourceCodeEnd":1389,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory/src/integrations/platform/github/integration.ts#L1353-L1389","documentation":"Thrown by the private #createReviewComment helper when creating a (non-reply) GitHub pull request review comment without the required fields: commitId, path, line, and side. GitHub's API needs these to anchor the comment to a diff position; replies are exempt because they anchor to the parent comment instead.","triggerScenarios":"Calling the review-comment capability with input.replyToId undefined and any of commitId empty, path empty, line undefined, or side missing.","commonSituations":"Tool/agent calls that build the comment body but skip diff-position fields; UI flows where the user picks a file but never selects a line/side; passing line: 0 or empty-string path from unvalidated input.","solutions":["Populate commitId, path, line, and side on the input before calling the API","If responding to an existing comment, set replyToId instead of the anchoring fields","Validate the input shape before invoking (see validationCode)","Fetch the commit SHA of the reviewed head to supply commitId"],"exampleFix":"// before\nawait github.createReviewComment({ installationId, sourceId, pullRequestId, body: 'nit:' });\n// after\nawait github.createReviewComment({ installationId, sourceId, pullRequestId, body: 'nit:', commitId: headSha, path: 'src/index.ts', line: 42, side: 'RIGHT' });","handlingStrategy":"validation","validationCode":"function validateReviewComment(input: CreateReviewCommentInput): string | null {\n  if (input.replyToId !== undefined) return null;\n  if (!input.commitId) return 'commitId is required';\n  if (!input.path) return 'path is required';\n  if (input.line === undefined) return 'line is required';\n  if (!input.side) return 'side is required';\n  return null;\n}","typeGuard":"function isAnchoredReviewComment(i: CreateReviewCommentInput): boolean {\n  return i.replyToId !== undefined || (!!i.commitId && !!i.path && i.line !== undefined && !!i.side);\n}","tryCatchPattern":"try {\n  await github.createReviewComment(input);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith('A review comment requires')) {\n    // fall back to posting a plain PR comment or prompt the user for line/side\n  } else throw err;\n}","preventionTips":["Always capture head commit SHA, file path, line, and side when building review UI state","Prefer replyToId for threaded responses instead of duplicating anchor fields","Validate comment inputs in the UI before submitting","Treat line/side as required form fields for new (non-reply) comments"],"tags":["github","validation","pull-request","review-comment"],"backgroundTag":"missing-required-field","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}