Non-existent volume returns 502 instead of 404 — error handler mismatch #26

Closed
opened 2026-05-14 13:22:28 +00:00 by Mark · 1 comment
Owner

Bug

Querying a non-existent Docker volume returns HTTP 502 with "Failed to inspect Docker volume" instead of 404 with "Volume not found".

Evidence

$ curl -s http://localhost:3001/api/volumes/nonexistent
{"error":"Failed to inspect Docker volume"}  # HTTP 502

Expected:

{"error":"Volume not found"}  # HTTP 404

Root Cause

The isNotFoundError check in volumes.ts (line 26-33) looks for statusCode === 404 on the error object, but Dockerode's error shape doesn't match this pattern. The check never passes, so all volume errors fall through to the 502 catch-all.

const isNotFoundError = (error: unknown): boolean => {
  if (error && typeof error === "object" && "statusCode" in error) {
    const statusCode = (error as { statusCode?: number }).statusCode;
    return statusCode === 404;
  }
  return false;
};

This affects 4 endpoints:

  • GET /volumes/:id (line 51)
  • GET /volumes/:id/backups (line 75)
  • POST /volumes/:id/restore (line 121)
  • POST /volumes/:id/backup (line 159)

Severity

YELLOW Medium — Bad HTTP semantics. API consumers can't distinguish "volume not found" (retry with different ID) from "server broke" (retry later).

## Bug Querying a non-existent Docker volume returns HTTP 502 with "Failed to inspect Docker volume" instead of 404 with "Volume not found". ## Evidence ``` $ curl -s http://localhost:3001/api/volumes/nonexistent {"error":"Failed to inspect Docker volume"} # HTTP 502 ``` Expected: ``` {"error":"Volume not found"} # HTTP 404 ``` ## Root Cause The `isNotFoundError` check in `volumes.ts` (line 26-33) looks for `statusCode === 404` on the error object, but Dockerode's error shape doesn't match this pattern. The check never passes, so all volume errors fall through to the 502 catch-all. ```typescript const isNotFoundError = (error: unknown): boolean => { if (error && typeof error === "object" && "statusCode" in error) { const statusCode = (error as { statusCode?: number }).statusCode; return statusCode === 404; } return false; }; ``` This affects 4 endpoints: - `GET /volumes/:id` (line 51) - `GET /volumes/:id/backups` (line 75) - `POST /volumes/:id/restore` (line 121) - `POST /volumes/:id/backup` (line 159) ## Severity YELLOW **Medium** — Bad HTTP semantics. API consumers can't distinguish "volume not found" (retry with different ID) from "server broke" (retry later).
Author
Owner

Closed by pipeline sweep — no code changes required (blocked:no-changes). Fixer now auto-closes this case going forward.

Closed by pipeline sweep — no code changes required (blocked:no-changes). Fixer now auto-closes this case going forward.
Mark closed this issue 2026-05-20 19:38:57 +00:00
Sign in to join this conversation.
No description provided.