Skip to content

fix(providers): reject silent validation degradation with 400 and rejected keys - #11101

Merged
diegosouzapw merged 1 commit into
diegosouzapw:release/v3.8.50from
maxmad64bis:fix/05-ctr3-silent-validation
Aug 22, 2026
Merged

diegosouzapw merged 1 commit into
diegosouzapw:release/v3.8.50from
maxmad64bis:fix/05-ctr3-silent-validation

Conversation

@maxmad64bis

Copy link
Copy Markdown
Contributor

Summary

Unknown rateLimitOverrides keys (e.g. a typo'd tpm) and empty/non-numeric values were silently stripped by z.coerce.number() + non-strict object parsing, so an operator's intent vanished with a 200 OK. The schema now uses a .strict() object with a preprocess step that rejects empty strings and non-numeric input, and the DB sanitizers return {sanitized, rejected} and refuse the write on any rejected key. The 400 response surfaces the rejected key names.

Related Issues

  • Related to upstream provider connection PATCH validation.

Validation

  • Change type: providers / routing
  • Focused tests: node --import tsx/esm --test tests/unit/providers-patch-400.test.ts tests/unit/columns-validation.test.ts → 22 pass / 0 fail; npm run lint; npm run typecheck:core; npm run check:cycles
  • npm run lint
  • Reconciled with the current active release base (upstream/release/v3.8.50 3caa59107), focused checks rerun
  • Production-code changes include a new or updated automated test in this PR

Tests Added Or Updated

  • tests/unit/providers-patch-400.test.ts (new, 6 tests: coerce valid, unknown key rejected, >64 rejected, "" rejected, non-numeric rejected, quota 101 rejected)
  • tests/unit/columns-validation.test.ts (new, 3 tests: sanitizers surface rejected keys)

Coverage Notes

  • No src/ line coverage regression; the validation path and DB sanitizers are covered by the new unit tests.

Reviewer Notes

  • Breaking for direct DB writers: sanitizeRateLimitOverrides/sanitizeQuotaWindowThresholds now throw on rejected keys instead of pruning (API path unaffected since zod validates first).
  • The 400 envelope keeps the existing {error:{message,details}} shape and adds rejected (field paths + unrecognized key names) so the frontend consumer reading data.error?.message is unaffected.

…ected keys

Unknown rateLimitOverrides keys (e.g. a typo'd tpm) and empty/non-numeric
values were silently stripped by z.coerce.number() + non-strict object
parsing, so an operator's intent vanished with a 200 OK. The schema now
uses a .strict() object with a preprocess step that rejects empty strings
and non-numeric input, and the DB sanitizers return {sanitized, rejected}
and refuse the write on any rejected key. The 400 response surfaces the
rejected key names.
@maxmad64bis
maxmad64bis force-pushed the fix/05-ctr3-silent-validation branch from 3c9c269 to 885c6d7 Compare August 22, 2026 08:38
@diegosouzapw
diegosouzapw merged commit f3b190b into diegosouzapw:release/v3.8.50 Aug 22, 2026
9 of 16 checks passed
@maxmad64bis
maxmad64bis deleted the fix/05-ctr3-silent-validation branch September 24, 2026 21:12
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…ected keys (diegosouzapw#11101)

Validated on the combined batch board over release/v3.8.50 tip 0f43f0f: static gates clean, typecheck:core clean, focused tests green.

Strict schema + {sanitized, rejected} DB boundary — silent validation degradation now answers 400 with the offending keys. Caller audit done: only the providers write path consumes the sanitizers. Thank you @maxmad64bis!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants