Skip to content

Commit 74cc5a8

Browse files
committed
docs(changeset): name the import-path consequence of the #7534 filter gate
The gate sits at the `findData` ingress, so it also reaches the record-matching lookup the import runner performs for `update` / `upsert` writes. That is a user-visible behaviour change on a second surface, and someone who hits it must be able to find out why from the release notes rather than from a support thread. Records the old behaviour (a `matchField` naming no field silently degraded an upsert into an insert, returning `'none'`), the new one (that row fails with `400 INVALID_FIELD`, contained by the row loop's own try/catch so the rest of the import proceeds), the remedy, and that `resolveRef`'s speculative probes are unaffected because they already catch the absent-field case deliberately. Ruled on #7534: the failure stays. Exempting the import path would have meant ADDING code to preserve a silent data-correctness bug of the same family this change closes. Changeset only — no code changed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NxE7c6qf7Bi9ZQ7HtYrNUj
1 parent d01ae81 commit 74cc5a8

1 file changed

Lines changed: 36 additions & 0 deletions

File tree

.changeset/rest-list-explicit-filter-unknown-field.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,39 @@ infer from a `200`.
5757
`200` with `total: 0`. A filter that cannot be *run* at all is still
5858
`INVALID_FILTER` (#4121 / #4181), which answers first; this gate answers only
5959
"does this field exist".
60+
61+
## Upgrade note — data import: a `matchField` naming no field now fails the row
62+
63+
The gate sits at the `findData` ingress, so it also reaches the record-matching
64+
lookup the CSV/JSON import runner performs for `update` and `upsert` writes.
65+
This is a **user-visible behaviour change on a second surface**, and it is
66+
deliberate — the ruling on #7534 was to keep it rather than exempt the import
67+
path.
68+
69+
**Before.** A `matchFields` entry naming a field the target object does not have
70+
produced a filter that could only match zero rows. The lookup read that as
71+
`'none'` — "no existing record" — and an `upsert` therefore fell through to a
72+
**create**. The import reported success while writing duplicate rows the caller
73+
believed were being matched and updated, and nothing in the response
74+
distinguished that from a genuinely new record.
75+
76+
**Now.** That row fails with `400 INVALID_FIELD` naming the field. The failure
77+
is contained by the row loop's own `try`/`catch`, so it is reported as one
78+
failed row in the import results and **the rest of the import proceeds** — it is
79+
not an aborted job.
80+
81+
**Remedy.** Correct the `matchFields` name to a field that exists on the object.
82+
The rejection names the offending field and, when it reads like a typo, suggests
83+
the closest real field name.
84+
85+
Exempting the import path would have meant *adding* code — catching
86+
`INVALID_FIELD` and restoring `'none'` — to preserve a silent data-correctness
87+
bug of exactly the family this change closes, so the invariant is restored
88+
instead.
89+
90+
**Unaffected: reference resolution.** The import runner's `resolveRef` probes
91+
candidate display fields (`name`, `title`, `label`, `full_name`, `email`,
92+
`username`) that legitimately may not exist on the object being referenced, and
93+
it already wraps each probe in a deliberate `catch` that moves on to the next
94+
candidate. A `400` lands exactly where the empty result did, so reference
95+
resolution behaves as before.

0 commit comments

Comments
 (0)