Skip to content

fix: sporadic 'context cancelled' errors when adding downloads via HTTP API - #561

Merged
SuperCoolPencil merged 1 commit into
mainfrom
fix/enqueue-context-cancellation
Jul 28, 2026
Merged

fix: sporadic 'context cancelled' errors when adding downloads via HTTP API#561
SuperCoolPencil merged 1 commit into
mainfrom
fix/enqueue-context-cancellation

Conversation

@SuperCoolPencil

@SuperCoolPencil SuperCoolPencil commented Jul 28, 2026

Copy link
Copy Markdown
Member

Problem

Downloads added via the HTTP API (browser extension) randomly fail with:

Error adding: Link enqueue aborted: context cancelled

There is no rhyme or reason — retrying the exact same download immediately succeeds.

Root Cause

enqueueDownloadRequest() in cmd/root_downloads.go was passing r.Context() (the HTTP request context) to lifecycle.Enqueue().

The Enqueue function performs a server probe (HEAD request to check file size, range support, filename) which can take several seconds. The HTTP request context r.Context() gets cancelled when:

  • The HTTP handler returns
  • The browser extension client disconnects or times out

This creates a race: if the probe takes longer than the HTTP connection stays alive, the context is cancelled mid-probe, aborting the enqueue.

From the debug log:

  • First attempt (20:58:49): Probe starts, takes ~5s, fails with context canceled
  • Second attempt (20:59:09): Same URL, probe completes in ~1s, succeeds

Fix

Replaced r.Context() with currentEnqueueContext() — the application-level context that only cancels on shutdown. This matches what the TUI path (processDownloads) and CLI path already use correctly.

Testing

Added TestHandleDownload_DoesNotUseCancelledHTTPRequestContext which creates an HTTP request with a pre-cancelled context and verifies the download still enqueues successfully. All existing tests pass.

Greptile Summary

Fixes sporadic HTTP API enqueue failures by decoupling probe/enqueue from the HTTP request context.

  • enqueueDownloadRequest now passes currentEnqueueContext() into lifecycle.Enqueue / EnqueueWithID instead of r.Context(), matching CLI/TUI paths so client disconnect or handler return no longer aborts the server probe.
  • Adds TestHandleDownload_DoesNotUseCancelledHTTPRequestContext covering a pre-cancelled request context that still queues successfully.

Confidence Score: 5/5

This change appears safe to merge; the context change matches existing CLI/TUI enqueue lifetime and is covered by a focused regression test.

Enqueue uses the shared application cancel-on-shutdown context with a 30s probe timeout derived from it, avoiding request-context races without introducing a new failure mode on the changed path.

T-Rex T-Rex Logs

What T-Rex did

  • Ran the focused test TestHandleDownload_DoesNotUseCancelledHTTPRequestContext against the real cmd package and verified it passed.
  • Validated the narrow-suite regression evidence and confirmed the regression remains passing alongside the existing HTTP download handler coverage.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
cmd/root_downloads.go Switches HTTP enqueue to the process-level enqueue context so probe work is not cancelled by request lifetime.
cmd/http_handler_test.go Adds a regression test that enqueues successfully with an already-cancelled HTTP request context.

Sequence Diagram

sequenceDiagram
  participant Ext as Browser extension
  participant API as handleDownload
  participant Enq as enqueueDownloadRequest
  participant Life as Lifecycle.Enqueue
  participant Probe as ProbeServer

  Ext->>API: POST /download
  API->>Enq: enqueueDownloadRequest
  Note over Enq: ctx = currentEnqueueContext()<br/>(not r.Context())
  Enq->>Life: Enqueue(ctx, dlReq)
  Life->>Probe: probe (up to ~30s)
  Note over Ext,API: Client disconnect would cancel r.Context()<br/>but app enqueue ctx stays live
  Probe-->>Life: size/range/filename
  Life-->>Enq: id, filename
  Enq-->>API: ok
  API-->>Ext: 200 queued (if still connected)
Loading

Reviews (1): Last reviewed commit: "fix: use application-level context for H..." | Re-trigger Greptile

…ext()

The HTTP handler was passing r.Context() to lifecycle.Enqueue(), which gets
cancelled when the HTTP connection closes or the handler returns. Since the
server probe can take several seconds, the browser extension may disconnect
before the probe completes, causing sporadic 'context cancelled' errors on
otherwise valid downloads.

Switched to currentEnqueueContext() (the application-level context that only
cancels on shutdown), matching what the TUI and CLI paths already use.

Added a regression test that verifies downloads succeed even when the HTTP
request context is already cancelled.
@SuperCoolPencil

SuperCoolPencil commented Jul 28, 2026

Copy link
Copy Markdown
Member Author

@greptileai

@SuperCoolPencil
SuperCoolPencil merged commit 007fee7 into main Jul 28, 2026
15 checks passed
@SuperCoolPencil
SuperCoolPencil deleted the fix/enqueue-context-cancellation branch July 28, 2026 16:08
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.

1 participant