Atomic Work Item task-list toggle raises on an out-of-range stale source position
Summary
A task-list toggle created from an earlier Work Item description can refer to a line that no longer exists after another client replaces or shortens the description. Instead of following the existing recoverable concurrent-edit path, the update raises while comparing the missing line.
Steps to reproduce
- Enable the experimental
work_items_task_list_togglefeature. - Create a Work Item with:
Intro
- [ ] Task 1- Client A loads the Work Item and retains:
lineSource: "- [ ] Task 1"
lineSourcepos: "3:4-3:4"- Client B replaces the description with
Intro, so the original third line no longer exists. - Client A submits the original task-list toggle with
checked: true.
Current behavior
TaskListToggleService raises before its normal stale-input protocol can run:
NoMethodError: undefined method 'chomp' for nilIn the request-level regression, the Work Item GraphQL mutation produced a top-level internal error with no mutation data instead of the existing concurrent-edit response. This report does not characterize the HTTP status.
Expected behavior
The stale toggle should:
- not modify the shortened description;
- not toggle another line;
- use the existing concurrent-edit recovery path;
- return current Work Item state with the normal conflict error.
Root cause
current Markdown
→ split into lines
→ stale source line index is out of range
→ array lookup returns nil
→ chomp is called on nil
→ TaskListToggleService cannot return its normal falsey result
→ existing StaleObjectError recovery is bypassedWhy this is a bug
An existing in-range stale line_source already produces a normal unsuccessful toggle. IssuableBaseService converts that falsey result into the task-toggle-specific ActiveRecord::StaleObjectError. Mutations::WorkItems::Update catches that condition and returns a recoverable “Someone edited this…” response with current Work Item state.
A concurrently removed line is the same stale-input class and should follow that existing contract.
Affected versions
Dynamically reproduced on master commit:
44fa09d18de27fb46f9bbbc5e0037b662ad53ec7The same unsafe implementation was observed statically in GitLab 19.3.1. A second stable runtime reproduction was not performed.
The Work Item input is experimental, introduced in 19.2, and guarded by the default-disabled work_items_task_list_toggle feature flag.
Regression evidence
Before:
service regression → NoMethodError
After:
TaskListToggleService full spec → 26 examples, 0 failures
Work Item update mutation full spec → 131 examples, 0 failures
RuboCop → clean
git diff --check → cleanAdditional notes
A bounded public search found no obvious duplicate or open equivalent fix; private scope is unknown.
Origin issue: #582358 (closed) Atomic API introduction: !244520 (merged) Rollout tracking: #605619 (closed)