500 Internal Server Error when creating diff note via API - NoMethodError in PositionTracer#compare

(Text was generated by AI, but we have verified from logs that we're getting 500)

Summary:

When creating a merge request discussion thread via the REST API (POST /api/v4/projects/:id/merge_requests/:merge_request_iid/discussions), the server returns a 500 Internal Server Error instead of a meaningful error message. Even if the request parameters are invalid, users should receive a 400/422 response with details about what's wrong.

GitLab Version: 18.6 (self-managed)

Steps to reproduce:

1. Create a merge request with at least one changed file
2. Use the Discussions API to create a diff note with position parameters
3. Under certain conditions (exact trigger unclear), the request fails with 500

From

https://docs.gitlab.com/api/merge_requests/#get-merge-request-diff-versions

I'm sending { "body": "Review comment", "position": { "base_sha": "", "start_sha": "", "head_sha": "", "position_type": "text", "old_path": "README.md", "new_path": "README.md", "new_line": 7 }

And getting back just 500.

In logs

{ "severity": "ERROR", "time": "2026-01-08T11:36:42.578Z", "correlation_id": "01KEEPA1PKSCW8RCK0QVEF0TFA", "meta.caller_id": "POST /api/:version/projects/:id/merge_requests/:noteable_id/discussions", "meta.feature_category": "code_review_workflow", "exception.class": "NoMethodError", "exception.message": "undefined method `diffs' for nil:NilClass", "exception.backtrace": [ "lib/gitlab/diff/position_tracer.rb:63:in `compare'", "lib/gitlab/diff/position_tracer.rb:30:in `ac_diffs'", "lib/gitlab/diff/position_tracer/base_strategy.rb:9:in `ac_diffs'", "lib/gitlab/diff/position_tracer/line_strategy.rb:154:in `trace_unchanged_line'", "lib/gitlab/diff/position_tracer/line_strategy.rb:72:in `trace'", "lib/gitlab/diff/position_tracer.rb:26:in `trace'", "app/models/concerns/diff_positionable_note.rb:90:in `update_position'", "app/services/notes/create_service.rb:17:in `block in execute'", "lib/api/helpers/notes_helpers.rb:161:in `create_note'", "lib/api/discussions.rb:128:in `block (3 levels) in <class:Discussions>'" ] }

Expected result:

If the position parameters are invalid or the diff cannot be traced, the API should return a 400 or 422 response with a descriptive error message (e.g., "Unable to locate diff position" or "Invalid line reference for the specified SHA").

Root cause analysis (AI):

The PositionTracer#compare method at lib/gitlab/diff/position_tracer.rb:63 returns nil, and the subsequent call to .diffs on this nil object causes the unhandled NoMethodError. The code path through trace_unchanged_line suggests this may be related to positioning on context lines.

Edited Jan 08, 2026 by 🤖 GitLab Bot 🤖
Assignee Loading
Time tracking Loading