Skip to content

fix: nil pointer dereference in UpdateRunner when task not in pool#3727

Merged
fiftin merged 1 commit intodevelopfrom
cursor/critical-bug-inspection-ed07
Mar 28, 2026
Merged

fix: nil pointer dereference in UpdateRunner when task not in pool#3727
fiftin merged 1 commit intodevelopfrom
cursor/critical-bug-inspection-ed07

Conversation

@cursor
Copy link
Copy Markdown

@cursor cursor bot commented Mar 28, 2026

Bug and Impact

Nil pointer dereference (server crash) in UpdateRunner (api/runners/runners.go).

When a remote runner reports progress for a task that is no longer in the local memory pool (e.g. it already finished and was removed), GetTask returns (nil, nil). The code then dereferences tsk.RunnerID without a nil check, causing a panic that crashes the HTTP handler and returns a 500 to the runner.

Trigger scenario: Any non-HA deployment where a remote runner sends a progress update for a task that has already finished and been cleaned up from the in-memory task pool. This is a normal race condition in production — runners poll on a 1-second interval and the task can finish between polls.

Root Cause

The recent refactoring (commit 55422e02 and related HA work) changed GetTask from returning *TaskRunner to (*TaskRunner, error). The old call sites in UpdateRunner previously had an explicit nil-check-then-hydrate pattern. The refactored code correctly checks err != nil but removed the tsk == nil check. GetTask only hydrates from DB when HAEnabled() is true, so on non-HA setups GetTask can return (nil, nil).

Fix

  1. api/runners/runners.go: Added the missing tsk == nil guard after the error check, logging a warning and continuing to the next job (matching the prior behavior).

  2. services/tasks/TaskPool.go (secondary fix): In StopTasksByTemplate, the error log on line 631 used err (which is always nil at that point — it was checked earlier) instead of taskErr. This masked actual errors during the stop-all-tasks-by-template operation.

Validation

  • Both affected packages (api/runners, services/tasks) compile cleanly.
  • Existing tests in services/tasks pass.
  • Changes are minimal and surgical — no refactoring or unrelated modifications.
Open in Web View Automation 

GetTask now returns (nil, nil) when HA is disabled and a task is
not in the local memory pool. The refactored UpdateRunner skipped
the nil check for tsk, causing a panic on tsk.RunnerID access.

Also fix StopTasksByTemplate logging the wrong error variable
(err instead of taskErr), which always logged nil.

Co-authored-by: Denis Gukov <[email protected]>
@fiftin fiftin marked this pull request as ready for review March 28, 2026 18:56
@fiftin fiftin changed the base branch from develop to 2-17-stable March 28, 2026 18:57
@fiftin fiftin changed the base branch from 2-17-stable to develop March 28, 2026 18:57
Copy link
Copy Markdown
Author

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Review

Result: No security issues found.

I reviewed both changes in this PR for injection risks, auth/authz bypasses, information disclosure, and DoS vectors:

  • Nil guard in UpdateRunner (api/runners/runners.go): The added tsk == nil check correctly prevents a nil pointer dereference (panic/crash) when a runner reports progress on a task no longer in the pool. The endpoint is protected by RunnerMiddleware (token-based auth), and the nil path logs server-side only — no sensitive data is returned to the caller. This is a net security improvement (prevents authenticated-runner-triggered DoS via panic).

  • Logging fix in StopTasksByTemplate (services/tasks/TaskPool.go): Replacing err with taskErr is a correctness-only change with no security impact.

No new attack surface, no auth bypass, no information leakage introduced.

Open in Web View Automation 

Sent by Cursor Automation: Find vulnerabilities

@fiftin fiftin merged commit 12fe721 into develop Mar 28, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants