From cab1b84afed0009ca81d0af83248c079b96a5e78 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 19 Oct 2026 23:11:01 +0000 Subject: [PATCH 1/2] fix(spec): describe CompleteUploadRequest.eTag as stored, not compared Co-authored-by: Claude Claude-Session: https://claude.ai/code/session_01D6F9axfoPzR7t8G1J7Ytzz --- packages/spec/src/api/storage.zod.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/spec/src/api/storage.zod.ts b/packages/spec/src/api/storage.zod.ts index 0f103448026..ba47c422edd 100644 --- a/packages/spec/src/api/storage.zod.ts +++ b/packages/spec/src/api/storage.zod.ts @@ -73,7 +73,12 @@ export const GetPresignedUrlRequestSchema = lazySchema(() => z.object({ export const CompleteUploadRequestSchema = lazySchema(() => z.object({ fileId: z.string().describe('File ID returned from presigned request'), - eTag: z.string().optional().describe('S3 ETag verification'), + eTag: z.string().optional().describe( + 'ETag the client reports for the uploaded object. Stored on the file record as sent and not compared ' + + 'with anything: no storage adapter reports a stored object\'s ETag. Before committing, the door checks ' + + 'that the storage backend holds bytes under the file\'s key and, when the upload declared a size, ' + + 'that the held size equals it.', + ), })); // ========================================== From bbe6b223b901dc48a966ce3de67c43638d0a7cdb Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 19 Oct 2026 23:20:37 +0000 Subject: [PATCH 2/2] docs(spec): regenerate storage reference and add changeset for the eTag describe Co-authored-by: Claude Claude-Session: https://claude.ai/code/session_01D6F9axfoPzR7t8G1J7Ytzz --- .changeset/24648-etag-describe.md | 5 +++++ content/docs/references/api/storage.mdx | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changeset/24648-etag-describe.md diff --git a/.changeset/24648-etag-describe.md b/.changeset/24648-etag-describe.md new file mode 100644 index 00000000000..9ffa4128585 --- /dev/null +++ b/.changeset/24648-etag-describe.md @@ -0,0 +1,5 @@ +--- +'@objectstack/spec': patch +--- + +`CompleteUploadRequestSchema.eTag` no longer describes itself as "S3 ETag verification". The upload completion door stores the client-reported value on the file record as sent and compares it with nothing, because no storage adapter reports a stored object's ETag. The description now says so, and names the check the door does run before committing: the storage backend must hold bytes under the file's key and, when the upload declared a size, hold exactly that many. The schema's shape is unchanged. diff --git a/content/docs/references/api/storage.mdx b/content/docs/references/api/storage.mdx index ec162537944..e9856b832dc 100644 --- a/content/docs/references/api/storage.mdx +++ b/content/docs/references/api/storage.mdx @@ -102,7 +102,7 @@ const result = CompleteChunkedUploadRequestSchema.parse(data); | Property | Type | Required | Description | | :--- | :--- | :--- | :--- | | **fileId** | `string` | ✅ | File ID returned from presigned request | -| **eTag** | `string` | optional | S3 ETag verification | +| **eTag** | `string` | optional | ETag the client reports for the uploaded object. Stored on the file record as sent and not compared with anything: no storage adapter reports a stored object's ETag. Before committing, the door checks that the storage backend holds bytes under the file's key and, when the upload declared a size, that the held size equals it. | ---