You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit a5302c7
Browse filesBrowse the repository at this point in the historyBrowse files
fix(service-storage): refuse a predicate update that writes a file field (#7102) (#7224)
A predicate (`multi: true`) update has ONE payload for N matched rows, so a
file id written through one landed in every matched record while at most one
of them could own it — read authorisation for those bytes then derived from a
record the others have nothing to do with, which is the exact widening the
exclusive-ownership design exists to prevent. Two log warnings were the only
signal and nothing failed.
That write is now refused in `beforeUpdate`, before the driver runs, with an
ADR-0112 envelope error (`FILE_FIELD_BULK_WRITE_REFUSED` / 400). The refusal
is scoped to a file id TOKEN reaching a file-class field — decided by
`isFileIdToken`, the same arbiter copy-on-claim already uses — so a bulk clear,
an external URL and a legacy inline blob still work per row, and every
single-record path is byte-identical.
Claude-Session: https://claude.ai/code/session_015fkdTyGmMD5s8ZtEifvuGy
Co-authored-by: Claude <noreply@anthropic.com>
|**data**|`{ name: string; title?: string; measures: object[]; dimensions: object[] }[]`| ✅ | Available cubes, each as the `CubeMeta` discovery projection — the cube name, its title, and the measures/dimensions a client may name in a query. A bare array: there is no `cubes` wrapper object, and no cube `sql` is published. |
50
50
@@ -79,7 +79,7 @@ const result = AnalyticsEndpoint.parse(data);
79
79
| Property | Type | Required | Description |
80
80
| :--- | :--- | :--- | :--- |
81
81
|**success**|`boolean`| ✅ | Operation success status |
Copy file name to clipboardExpand all lines: content/docs/references/api/batch.mdx
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -55,7 +55,7 @@ const result = BatchConfigSchema.parse(data);
55
55
| :--- | :--- | :--- | :--- |
56
56
|**id**|`string`| optional | Record ID if operation succeeded |
57
57
|**success**|`boolean`| ✅ | Whether this record was processed successfully |
58
-
|**errors**|`{ code: Enum<'VALIDATION_ERROR' \| 'INVALID_FIELD' \| 'MISSING_REQUIRED_FIELD' \| … +257 more>; message: string; category?: string; httpStatus?: integer; … }[]`| optional | Array of errors if operation failed. Branch on `errors[0].code` — an atomic batch that rolled back marks rows that were written then undone with code ROLLED_BACK and rows never reached with NOT_ATTEMPTED, while the causal row keeps its own error (#4793). |
58
+
|**errors**|`{ code: Enum<'VALIDATION_ERROR' \| 'INVALID_FIELD' \| 'MISSING_REQUIRED_FIELD' \| … +258 more>; message: string; category?: string; httpStatus?: integer; … }[]`| optional | Array of errors if operation failed. Branch on `errors[0].code` — an atomic batch that rolled back marks rows that were written then undone with code ROLLED_BACK and rows never reached with NOT_ATTEMPTED, while the causal row keeps its own error (#4793). |
59
59
|**data**|`Record<string, any>`| optional | Full record data (if returnRecords=true) |
60
60
|**index**|`number`| optional | Index of the record in the request array |
61
61
|**droppedFields**|`{ object: string; fields: string[]; reason: Enum<'readonly' \| 'readonly_when' \| 'primary_key'> }[]`| optional | Write-observability (#3407/#3431/#3455): caller-supplied fields LEGALLY stripped from THIS row before it was written — static `readonly` (#2948) / TRUE `readonlyWhen` (#3042) on update, or the #3043 create-ingress strip. Per-row because a batch can drop different fields on different rows (`readonlyWhen` is record-state-dependent). Present ONLY when ≥1 field was dropped for this row; the row still succeeded (success unchanged). A single response header cannot express per-row drops, so this body field is the canonical bulk channel — REST does not emit `X-ObjectStack-Dropped-Fields` for batches. Optional — omit-when-empty keeps the shape backward-compatible. |
@@ -122,7 +122,7 @@ const result = BatchConfigSchema.parse(data);
122
122
| Property | Type | Required | Description |
123
123
| :--- | :--- | :--- | :--- |
124
124
|**success**|`boolean`| ✅ | Operation success status |
0 commit comments