fix(config): append numeric bound hints to ceiling/floor validation errors#84852
Conversation
…rrors When a config value exceeds a schema-enforced ceiling or falls below a floor, the error message now includes the constraint explicitly: - Inclusive: `(maximum: 20)` / `(minimum: 0)` - Exclusive: `(must be less than 5)` / `(must be greater than 0)` This matches the clarity that enum/union rejections already get via `(allowed: …)` hints, and avoids the misleading "minimum: 0" wording that previous attempts produced for `.positive()` / `.gt(0)` rejections. Only numeric-origin `too_big`/`too_small` issues are enriched; string, array, and file-size origins are left unchanged. Fixes openclaw#52500 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Codex review: needs maintainer review before merge. Workflow note: Future ClawSweeper reviews update this same comment in place. How this review workflow works
Summary Reproducibility: yes. source-reproducible: current main maps Zod issues to the raw message without numeric-bound enrichment, and the session schema has a capped numeric config value. I did not execute tests because this review was read-only. PR rating Rank-up moves:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. Real behavior proof Risk before merge
Maintainer options:
Next step before merge Security Review detailsBest possible solution: Land the narrow mapper and regression-test change after normal checks, then let the linked config ceiling issue close from the merge. Do we have a high-confidence way to reproduce the issue? Yes, source-reproducible: current main maps Zod issues to the raw message without numeric-bound enrichment, and the session schema has a capped numeric config value. I did not execute tests because this review was read-only. Is this the best way to solve the issue? Yes, the proposed shape is the narrowest maintainable fix: it uses Zod's numeric Label changes:
Label justifications:
What I checked:
Likely related people:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 9ec9fbf58d86. |
The test snapshot for `logging.maxFileBytes: 0` rejection now includes the `(must be greater than 0)` hint appended by the numeric bound enrichment added in the previous commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
ClawSweeper PR egg ✨ Hatched: 🌱 uncommon Sunspot Diff Drake Hatch commandComment Hatchability rules:
Rarity: 🌱 uncommon. What is this egg doing here?
|
ClawSweeper P1: `record` from `toIssueRecord()` can be null, but `appendNumericBoundHint` expects a non-null `UnknownIssueRecord`. Guard with a ternary so the original message is returned when record is null (which only happens for malformed/empty issues that already produce generic "Invalid input" messages). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This comment was marked as low quality.
This comment was marked as low quality.
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
…rrors (openclaw#84852) * fix(config): append numeric bound hints to ceiling/floor validation errors When a config value exceeds a schema-enforced ceiling or falls below a floor, the error message now includes the constraint explicitly: - Inclusive: `(maximum: 20)` / `(minimum: 0)` - Exclusive: `(must be less than 5)` / `(must be greater than 0)` This matches the clarity that enum/union rejections already get via `(allowed: …)` hints, and avoids the misleading "minimum: 0" wording that previous attempts produced for `.positive()` / `.gt(0)` rejections. Only numeric-origin `too_big`/`too_small` issues are enriched; string, array, and file-size origins are left unchanged. Fixes openclaw#52500 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(config): update maxFileBytes test for numeric bound hint The test snapshot for `logging.maxFileBytes: 0` rejection now includes the `(must be greater than 0)` hint appended by the numeric bound enrichment added in the previous commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(config): guard nullable record in appendNumericBoundHint call ClawSweeper P1: `record` from `toIssueRecord()` can be null, but `appendNumericBoundHint` expects a non-null `UnknownIssueRecord`. Guard with a ternary so the original message is returned when record is null (which only happens for malformed/empty issues that already produce generic "Invalid input" messages). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: tanshanshan <tanshanshan@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…rrors (openclaw#84852) * fix(config): append numeric bound hints to ceiling/floor validation errors When a config value exceeds a schema-enforced ceiling or falls below a floor, the error message now includes the constraint explicitly: - Inclusive: `(maximum: 20)` / `(minimum: 0)` - Exclusive: `(must be less than 5)` / `(must be greater than 0)` This matches the clarity that enum/union rejections already get via `(allowed: …)` hints, and avoids the misleading "minimum: 0" wording that previous attempts produced for `.positive()` / `.gt(0)` rejections. Only numeric-origin `too_big`/`too_small` issues are enriched; string, array, and file-size origins are left unchanged. Fixes openclaw#52500 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(config): update maxFileBytes test for numeric bound hint The test snapshot for `logging.maxFileBytes: 0` rejection now includes the `(must be greater than 0)` hint appended by the numeric bound enrichment added in the previous commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(config): guard nullable record in appendNumericBoundHint call ClawSweeper P1: `record` from `toIssueRecord()` can be null, but `appendNumericBoundHint` expects a non-null `UnknownIssueRecord`. Guard with a ternary so the original message is returned when record is null (which only happens for malformed/empty issues that already produce generic "Invalid input" messages). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: tanshanshan <tanshanshan@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…rrors (openclaw#84852) * fix(config): append numeric bound hints to ceiling/floor validation errors When a config value exceeds a schema-enforced ceiling or falls below a floor, the error message now includes the constraint explicitly: - Inclusive: `(maximum: 20)` / `(minimum: 0)` - Exclusive: `(must be less than 5)` / `(must be greater than 0)` This matches the clarity that enum/union rejections already get via `(allowed: …)` hints, and avoids the misleading "minimum: 0" wording that previous attempts produced for `.positive()` / `.gt(0)` rejections. Only numeric-origin `too_big`/`too_small` issues are enriched; string, array, and file-size origins are left unchanged. Fixes openclaw#52500 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(config): update maxFileBytes test for numeric bound hint The test snapshot for `logging.maxFileBytes: 0` rejection now includes the `(must be greater than 0)` hint appended by the numeric bound enrichment added in the previous commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(config): guard nullable record in appendNumericBoundHint call ClawSweeper P1: `record` from `toIssueRecord()` can be null, but `appendNumericBoundHint` expects a non-null `UnknownIssueRecord`. Guard with a ternary so the original message is returned when record is null (which only happens for malformed/empty issues that already produce generic "Invalid input" messages). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: tanshanshan <tanshanshan@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…rrors (openclaw#84852) * fix(config): append numeric bound hints to ceiling/floor validation errors When a config value exceeds a schema-enforced ceiling or falls below a floor, the error message now includes the constraint explicitly: - Inclusive: `(maximum: 20)` / `(minimum: 0)` - Exclusive: `(must be less than 5)` / `(must be greater than 0)` This matches the clarity that enum/union rejections already get via `(allowed: …)` hints, and avoids the misleading "minimum: 0" wording that previous attempts produced for `.positive()` / `.gt(0)` rejections. Only numeric-origin `too_big`/`too_small` issues are enriched; string, array, and file-size origins are left unchanged. Fixes openclaw#52500 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(config): update maxFileBytes test for numeric bound hint The test snapshot for `logging.maxFileBytes: 0` rejection now includes the `(must be greater than 0)` hint appended by the numeric bound enrichment added in the previous commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(config): guard nullable record in appendNumericBoundHint call ClawSweeper P1: `record` from `toIssueRecord()` can be null, but `appendNumericBoundHint` expects a non-null `UnknownIssueRecord`. Guard with a ternary so the original message is returned when record is null (which only happens for malformed/empty issues that already produce generic "Invalid input" messages). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: tanshanshan <tanshanshan@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…rrors (openclaw#84852) * fix(config): append numeric bound hints to ceiling/floor validation errors When a config value exceeds a schema-enforced ceiling or falls below a floor, the error message now includes the constraint explicitly: - Inclusive: `(maximum: 20)` / `(minimum: 0)` - Exclusive: `(must be less than 5)` / `(must be greater than 0)` This matches the clarity that enum/union rejections already get via `(allowed: …)` hints, and avoids the misleading "minimum: 0" wording that previous attempts produced for `.positive()` / `.gt(0)` rejections. Only numeric-origin `too_big`/`too_small` issues are enriched; string, array, and file-size origins are left unchanged. Fixes openclaw#52500 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(config): update maxFileBytes test for numeric bound hint The test snapshot for `logging.maxFileBytes: 0` rejection now includes the `(must be greater than 0)` hint appended by the numeric bound enrichment added in the previous commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(config): guard nullable record in appendNumericBoundHint call ClawSweeper P1: `record` from `toIssueRecord()` can be null, but `appendNumericBoundHint` expects a non-null `UnknownIssueRecord`. Guard with a ternary so the original message is returned when record is null (which only happens for malformed/empty issues that already produce generic "Invalid input" messages). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: tanshanshan <tanshanshan@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…rrors (openclaw#84852) * fix(config): append numeric bound hints to ceiling/floor validation errors When a config value exceeds a schema-enforced ceiling or falls below a floor, the error message now includes the constraint explicitly: - Inclusive: `(maximum: 20)` / `(minimum: 0)` - Exclusive: `(must be less than 5)` / `(must be greater than 0)` This matches the clarity that enum/union rejections already get via `(allowed: …)` hints, and avoids the misleading "minimum: 0" wording that previous attempts produced for `.positive()` / `.gt(0)` rejections. Only numeric-origin `too_big`/`too_small` issues are enriched; string, array, and file-size origins are left unchanged. Fixes openclaw#52500 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(config): update maxFileBytes test for numeric bound hint The test snapshot for `logging.maxFileBytes: 0` rejection now includes the `(must be greater than 0)` hint appended by the numeric bound enrichment added in the previous commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(config): guard nullable record in appendNumericBoundHint call ClawSweeper P1: `record` from `toIssueRecord()` can be null, but `appendNumericBoundHint` expects a non-null `UnknownIssueRecord`. Guard with a ternary so the original message is returned when record is null (which only happens for malformed/empty issues that already produce generic "Invalid input" messages). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: tanshanshan <tanshanshan@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…rrors (openclaw#84852) * fix(config): append numeric bound hints to ceiling/floor validation errors When a config value exceeds a schema-enforced ceiling or falls below a floor, the error message now includes the constraint explicitly: - Inclusive: `(maximum: 20)` / `(minimum: 0)` - Exclusive: `(must be less than 5)` / `(must be greater than 0)` This matches the clarity that enum/union rejections already get via `(allowed: …)` hints, and avoids the misleading "minimum: 0" wording that previous attempts produced for `.positive()` / `.gt(0)` rejections. Only numeric-origin `too_big`/`too_small` issues are enriched; string, array, and file-size origins are left unchanged. Fixes openclaw#52500 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(config): update maxFileBytes test for numeric bound hint The test snapshot for `logging.maxFileBytes: 0` rejection now includes the `(must be greater than 0)` hint appended by the numeric bound enrichment added in the previous commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(config): guard nullable record in appendNumericBoundHint call ClawSweeper P1: `record` from `toIssueRecord()` can be null, but `appendNumericBoundHint` expects a non-null `UnknownIssueRecord`. Guard with a ternary so the original message is returned when record is null (which only happens for malformed/empty issues that already produce generic "Invalid input" messages). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: tanshanshan <tanshanshan@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…rrors (openclaw#84852) * fix(config): append numeric bound hints to ceiling/floor validation errors When a config value exceeds a schema-enforced ceiling or falls below a floor, the error message now includes the constraint explicitly: - Inclusive: `(maximum: 20)` / `(minimum: 0)` - Exclusive: `(must be less than 5)` / `(must be greater than 0)` This matches the clarity that enum/union rejections already get via `(allowed: …)` hints, and avoids the misleading "minimum: 0" wording that previous attempts produced for `.positive()` / `.gt(0)` rejections. Only numeric-origin `too_big`/`too_small` issues are enriched; string, array, and file-size origins are left unchanged. Fixes openclaw#52500 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(config): update maxFileBytes test for numeric bound hint The test snapshot for `logging.maxFileBytes: 0` rejection now includes the `(must be greater than 0)` hint appended by the numeric bound enrichment added in the previous commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(config): guard nullable record in appendNumericBoundHint call ClawSweeper P1: `record` from `toIssueRecord()` can be null, but `appendNumericBoundHint` expects a non-null `UnknownIssueRecord`. Guard with a ternary so the original message is returned when record is null (which only happens for malformed/empty issues that already produce generic "Invalid input" messages). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: tanshanshan <tanshanshan@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…rrors (openclaw#84852) * fix(config): append numeric bound hints to ceiling/floor validation errors When a config value exceeds a schema-enforced ceiling or falls below a floor, the error message now includes the constraint explicitly: - Inclusive: `(maximum: 20)` / `(minimum: 0)` - Exclusive: `(must be less than 5)` / `(must be greater than 0)` This matches the clarity that enum/union rejections already get via `(allowed: …)` hints, and avoids the misleading "minimum: 0" wording that previous attempts produced for `.positive()` / `.gt(0)` rejections. Only numeric-origin `too_big`/`too_small` issues are enriched; string, array, and file-size origins are left unchanged. Fixes openclaw#52500 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(config): update maxFileBytes test for numeric bound hint The test snapshot for `logging.maxFileBytes: 0` rejection now includes the `(must be greater than 0)` hint appended by the numeric bound enrichment added in the previous commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(config): guard nullable record in appendNumericBoundHint call ClawSweeper P1: `record` from `toIssueRecord()` can be null, but `appendNumericBoundHint` expects a non-null `UnknownIssueRecord`. Guard with a ternary so the original message is returned when record is null (which only happens for malformed/empty issues that already produce generic "Invalid input" messages). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: tanshanshan <tanshanshan@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…rrors (openclaw#84852) * fix(config): append numeric bound hints to ceiling/floor validation errors When a config value exceeds a schema-enforced ceiling or falls below a floor, the error message now includes the constraint explicitly: - Inclusive: `(maximum: 20)` / `(minimum: 0)` - Exclusive: `(must be less than 5)` / `(must be greater than 0)` This matches the clarity that enum/union rejections already get via `(allowed: …)` hints, and avoids the misleading "minimum: 0" wording that previous attempts produced for `.positive()` / `.gt(0)` rejections. Only numeric-origin `too_big`/`too_small` issues are enriched; string, array, and file-size origins are left unchanged. Fixes openclaw#52500 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(config): update maxFileBytes test for numeric bound hint The test snapshot for `logging.maxFileBytes: 0` rejection now includes the `(must be greater than 0)` hint appended by the numeric bound enrichment added in the previous commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(config): guard nullable record in appendNumericBoundHint call ClawSweeper P1: `record` from `toIssueRecord()` can be null, but `appendNumericBoundHint` expects a non-null `UnknownIssueRecord`. Guard with a ternary so the original message is returned when record is null (which only happens for malformed/empty issues that already produce generic "Invalid input" messages). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: tanshanshan <tanshanshan@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…rrors (openclaw#84852) * fix(config): append numeric bound hints to ceiling/floor validation errors When a config value exceeds a schema-enforced ceiling or falls below a floor, the error message now includes the constraint explicitly: - Inclusive: `(maximum: 20)` / `(minimum: 0)` - Exclusive: `(must be less than 5)` / `(must be greater than 0)` This matches the clarity that enum/union rejections already get via `(allowed: …)` hints, and avoids the misleading "minimum: 0" wording that previous attempts produced for `.positive()` / `.gt(0)` rejections. Only numeric-origin `too_big`/`too_small` issues are enriched; string, array, and file-size origins are left unchanged. Fixes openclaw#52500 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(config): update maxFileBytes test for numeric bound hint The test snapshot for `logging.maxFileBytes: 0` rejection now includes the `(must be greater than 0)` hint appended by the numeric bound enrichment added in the previous commit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(config): guard nullable record in appendNumericBoundHint call ClawSweeper P1: `record` from `toIssueRecord()` can be null, but `appendNumericBoundHint` expects a non-null `UnknownIssueRecord`. Guard with a ternary so the original message is returned when record is null (which only happens for malformed/empty issues that already produce generic "Invalid input" messages). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: tanshanshan <tanshanshan@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
too_big/too_smallissues with numeric origin(maximum: 20)/(minimum: 0)(must be less than 5)/(must be greater than 0)(allowed: …)hintsFixes #52500
Motivation
When a config value exceeds a schema-enforced ceiling, the error message omits the maximum allowed value. Operators are told their value was rejected but not what value would be accepted. Previous attempts (#62091, #73220, #83916) were all closed without merging (author capacity / queue noise / too-many-PRs bot), leaving the issue unfixed.
Change Type
Scope
src/config/validation.ts—appendNumericBoundHint()+mapZodIssueToConfigIssue()enrichmentsrc/config/validation.allowed-values.test.ts— 5 new test casessrc/config/logging-max-file-bytes.test.ts— snapshot update for enriched messageReal behavior proof
Behavior addressed: Config validation error messages for numeric ceiling/floor rejections now include the bound value explicitly, matching the clarity that enum/union rejections get via
(allowed: …)hints.Real environment tested: Local checkout on main (cd019cf), Node 22.22, gateway build verified.
Exact steps or command run after this patch:
node --import tsx -e "import { validateConfigObjectRaw } from './src/config/validation.js'; import { formatConfigIssueLine } from './src/config/issue-format.js'; console.log(formatConfigIssueLine(validateConfigObjectRaw({ session: { agentToAgent: { maxPingPongTurns: 50 } } }).issues[0]));"Evidence after fix: Terminal output from
node --import tsxrunningvalidateConfigObjectRawdirectly against real config schema objects.Observed result after fix:
The
(maximum: 20),(minimum: 0), and(must be greater than 0)hints are the new enrichment. The enum(allowed: …)line shows existing behavior is unchanged.What was not tested: Full
pnpm checksuite; only scoped config validation invocations and colocated unit tests.Key design decisions
Not using
summarizeAllowedValueschain: that path JSON-stringifies string values, producing(allowed: "maximum: 20")with unwanted quotes. Numeric bounds and enum values are different semantics.origin !== "number"filter: avoids fix(config): include numeric bounds in schema validation errors #73220 P2 bug where string/array/file-sizetoo_bigissues would get misleading numeric range wording.inclusivedistinction:.max(20)→(maximum: 20)vs.lt(5)→(must be less than 5). Previous PR fix(config): include numeric bounds in schema validation errors #73220 incorrectly treated exclusive bounds as inclusive, saying "maximum: 5" when 5 itself is not allowed..positive()/.gt(0)correctness: these produceinclusive: false, minimum: 0. Output is(must be greater than 0), not the misleading(minimum: 0)that fix(config): include numeric bounds in schema validation errors #73220 produced.Nullable record guard:
toIssueRecord()returnsUnknownIssueRecord | null. When null, the original message is preserved (generic "Invalid input" for malformed issues).Security Impact
None. This only enriches error message text for config validation failures.