• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / storage / 38537002214
86%

Build:
DEFAULT BRANCH: master
Ran 14 Oct 2026 08:44AM UTC
Jobs 2
Files 319
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

14 Oct 2026 08:42AM UTC coverage: 85.352% (+0.02%) from 85.333%
38537002214

push

github

web-flow
feat(tus): object id in Supabase-Object-Id response header (#1500)

## What

Fixes [#647](https://github.com/supabase/storage/issues/647) — TUS
clients
had no way to resolve the storage row they just wrote without issuing a
follow-up list or search request.

Maintainer @fenos pre-approved the pattern on the issue in 2024:
> Yes! we could send the object_id back via a header like the upload-id.
> totally a legit enhancement

## Change

In `onUploadFinish` (`src/http/routes/tus/lifecycle.ts`):

```diff
- await uploader.completeUpload({ ... })
+ const completed = await uploader.completeUpload({ ... })

- return { headers: { 'Tus-Complete': '1' } }
+ const responseHeaders: Record<string, string> = { 'Tus-Complete': '1' }
+ if (completed?.obj?.id) {
+   responseHeaders['X-Supabase-Object-Id'] = String(completed.obj.id)
+ }
+ return { headers: responseHeaders }
```

- Header name follows the existing kebab-case convention
  (`Tus-Complete`, `Upload-ID`).
- Prefixed with `X-Supabase-` so it is unambiguously distinct from TUS
  protocol headers.
- Gracefully omitted if `completeUpload` returns without an id — the
  header is never emitted as the string `"undefined"`.

## Tests

Two new vitest cases in `src/http/routes/tus/lifecycle.test.ts`:

1. `includes X-Supabase-Object-Id when the created object id is
available`
   — happy path with a UUID.
2. `omits X-Supabase-Object-Id gracefully when completeUpload returns no
id`
   — defensive fallback.

Both use the existing `createRawTusRequest` helper + spies on
`Uploader.prototype.completeUpload`,
so they run without needing storage infrastructure.

## CORS note

Verified `src/app.ts:25` — CORS is handled by Kong upstream (`// kong
should
take care of cors`). No `Access-Control-Expose-Headers` change needed in
the app itself; operators who front the service without Kong already
configure header exposure at the reverse proxy.

## Impact

- Backwards compatible — adds a header, removes nothing. Older clients
  that ... (continued)

7624 of 9460 branches covered (80.59%)

Branch coverage included in aggregate %.

26 of 27 new or added lines in 2 files covered. (96.3%)

13300 of 15055 relevant lines covered (88.34%)

855.32 hits per line

Uncovered Changes

Lines Coverage ∆ File
1
83.2
1.55% src/http/routes/tus/lifecycle.ts
Jobs
ID Job ID Ran Files Coverage
1 rest-pg18 - 38537002214.1 14 Oct 2026 08:48AM UTC 299
63.68
GitHub Action Run
2 unit - 38537002214.2 14 Oct 2026 08:44AM UTC 313
66.75
GitHub Action Run
Source Files on build 38537002214
  • Tree
  • List 319
  • Changed 6
  • Source Changed 2
  • Coverage Changed 6
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Repo
  • Github Actions Build #38537002214
  • ca25d797 on github
  • Prev Build on master (#38490434153)
  • Next Build on master (#38543049882)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc