Repository navigation
Commit 836aad2
docs(error-catalog): VALUE_TOO_LONG / VALUE_TOO_SHORT name the field-level codes that really arrive (#20004)
Fixes #19879
Clause-②: no
## What
`content/docs/api/error-catalog.mdx`, the `VALUE_TOO_LONG` and
`VALUE_TOO_SHORT` entries only. Both entries gave a live cause and a
fix, as if a client could branch on the code. No producer emits either
code. Both entries now say so, following the shape the `INVALID_FORMAT`
entry got in #19878: the code is reserved, no route emits it today, and
a length miss arrives as a field-level `max_length` / `min_length`
entry. Each entry now says where that entry rides on each path: `400
VALIDATION_FAILED` with `fields[]` for record writes and Zod-parsed
request bodies (top-level on `/data`, under `details` through the
runtime dispatcher), and `400 SETTINGS_VALIDATION` with
`details.fields[]` for a settings write. The fix line names both
envelopes. Both entries stay because the enum still declares the codes.
## Evidence (measured on `origin/main` `e8f163fc`)
- **No producer.** `git grep -nE 'VALUE_TOO_(LONG|SHORT)'` outside tests
hits only the enum members `packages/spec/src/api/errors.zod.ts:58-59`,
the baseline rows `scripts/error-status-unpinned-baseline.json:27-28`,
this page, the generated `content/docs/references/**` pages, and
ADR-0114, which records these members as a known wart. A grep for other
spellings (`VALUE_TOO`, `TOO_LONG`, `TOO_SHORT`) finds only the
unrelated `PASSWORD_TOO_SHORT` in a plugin-auth test. Positive control:
`INVALID_FORMAT` hits `errors.zod.ts:57`.
- **Record writes.**
`packages/objectql/src/validation/record-validator.ts:695-699` sends
`fail('max_length', { maxLength, actual })` and `fail('min_length', {
minLength, actual })` for `BOUNDED_STRING_FIELD_TYPES`.
`buildFieldError` puts that object on the wire as `fields[].constraint`,
and the envelope's top-level code is `VALIDATION_FAILED`
(`VALIDATION_FAILED_CODE`, `:195`).
- **Zod-parsed request bodies.**
`packages/spec/src/api/zod-issues-to-fields.ts:74-81` maps `too_small` /
`too_big` to `min_length` / `max_length` when the value is not a number,
bigint, date, array or set. Numbers and dates map to `min_value` /
`max_value`, and arrays and sets to `min_items` / `max_items`. That is
why the page says "a string". The REST routes that use this send `code:
'VALIDATION_FAILED'` (for example
`packages/rest/src/rest-server.ts:8960-8963`).
- **Settings writes (a different envelope).**
`packages/services/service-settings/src/settings-service.ts:397-400`
returns `max_length` / `min_length` with `constraint { minLength?,
maxLength?, actual }` for a settings value outside its declared length
window. `:2145` pushes it into the errors list, and `:2167` throws
`SettingsValidationError` (`settings-service.types.ts:583-584`, `code =
'SETTINGS_VALIDATION'`).
`packages/services/service-settings/src/settings-routes.ts:215-217`
serves it as `sendError(res, 400, 'SETTINGS_VALIDATION', …, { details: {
namespace, fields } })`, and `packages/types/src/response-envelope.ts`
`sendError` writes that as `{ success: false, error: { code, message,
details } }`. So a settings length miss is top-level
`SETTINGS_VALIDATION` with the entry in `error.details.fields[]`, not
`VALIDATION_FAILED`.
- **Where `VALIDATION_FAILED` puts the list.** On the `/data` routes it
is flat (`packages/rest/src/error-response.ts:1152-1160`,
`mapDataError`: top-level `fields`). Through the runtime dispatcher it
is nested (`packages/runtime/src/dispatcher-plugin.ts:645`,
`validationFailureDetails`: `details.fields`). The page's own
`VALIDATION_FAILED` callout already documents both, so the entries link
to it rather than restating it.
- The field-level spellings are the same on all three paths:
`max_length` / `min_length`. The envelope differs: `VALIDATION_FAILED`
for records and Zod bodies, `SETTINGS_VALIDATION` for settings.
## Not touched
- The wire-count sentence at `:6`, the `CONCURRENT_LIMIT_EXCEEDED` entry
and `scripts/error-status-unpinned-baseline.json` are not changed. Open
PR #19957 edits them.
- `VALUE_OUT_OF_RANGE` and `MISSING_REQUIRED_FIELD` are not changed.
Both have producers.
- The page's frontmatter and headings are not changed.
## Changeset
None. This is a docs-only change under `content/docs/`, and no published
package's `files[]` changes, so it falls under `skip-changeset`. The PM
seat applies the label.
## Gates
Derived with `node scripts/pm/dispatch-gates.mjs --repo
objectstack-ai/objectstack --commands` from the merge-base change set (1
path). All 41 derived commands ran on HEAD `37431df1` and exited 0. The
derivation is unchanged from the first head, `ab8b19ea`. They include
`pnpm check:doc-authoring`, `pnpm check:doc-anchors`, `pnpm
check:nul-bytes`, `pnpm check:error-status-conformance`, `pnpm
check:docs-spec-enumerations` and `pnpm --filter @objectstack/spec run
check:docs`. The prerequisite closures (`lint` / `formula` /
`client-react`, which pulls in `spec`) were built under the verify lock
first. Reconciliation with `--ran` and the recorded exit codes: `41
derived, 41 run, 0 NOT-MEASURED, 0 UNRUN` (a derived zero). No package
source changed, so no package tests or typecheck are owed.
## Rework (PM review)
The first head said every length miss arrives in `VALIDATION_FAILED`,
which is wrong for settings writes. The second commit, `37431df1`, names
`SETTINGS_VALIDATION` + `details.fields[]` for that path in both the
Cause and the Fix lines. The `#validation_failed` link resolves:
`check:doc-anchors` passes, with 377 fragment links resolved.
## Acceptance notes
- The page's intro counts "52 error codes reachable on the wire", but
the page carries 53 code headings, and several of them are reserved
codes with no emitter (`INVALID_FORMAT`, `INVALID_REFERENCE`, and now
these two). Whether that count should include reserved codes is a
question for the line PR #19957 already edits. It is not changed here.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01VDtqoecgES7ScQYGbFVDRv)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 455dcc0 commit 836aad2
1 file changed
Lines changed: 30 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
215 | 215 | | |
216 | 216 | | |
217 | 217 | | |
218 | | - | |
219 | | - | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
220 | 233 | | |
221 | 234 | | |
222 | 235 | | |
223 | | - | |
224 | | - | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
225 | 251 | | |
226 | 252 | | |
227 | 253 | | |
| |||
0 commit comments