Skip to content

fix(server): emit numeric exclusive bounds for draft 2020-12 schemas - #76

Open
1ordo wants to merge 1 commit into
Dokploy:mainfrom
1ordo:fix/draft-2020-12-exclusive-bounds
Open

1ordo wants to merge 1 commit into
Dokploy:mainfrom
1ordo:fix/draft-2020-12-exclusive-bounds

Conversation

@1ordo

@1ordo 1ordo commented Aug 17, 2026

Copy link
Copy Markdown

Fixes #74

Root cause

toDraft2020_12JsonSchema converts with zod-to-json-schema using target: "jsonSchema2019-09", then stamps the result as draft 2020-12. zod-to-json-schema emits the numeric exclusiveMinimum/exclusiveMaximum form only for the jsonSchema7 target; every other target takes the non-draft-7 branch in parsers/number.js and emits the draft-4 pair:

{"type": "integer", "exclusiveMinimum": true, "minimum": 0, "maximum": 9007199254740991}

Draft 2020-12 requires a number there, so strict validators reject the whole tool list the moment dnsProvider-createRecord or dnsProvider-updateRecord is in the payload, exactly as reported in #74.

Fix

Switch the conversion target to jsonSchema7. To confirm this changes nothing else, I compared both targets across all 597 generated tools, ignoring the $schema key this function overwrites: the outputs are byte-identical except for the two affected tools, which now emit "exclusiveMinimum": 0.

Verification

Note: pnpm precommit fails on a clean checkout of main for an unrelated pre-existing formatting issue in redactSensitive.test.ts; #75 fixes that separately.

zod-to-json-schema only emits the numeric exclusiveMinimum and
exclusiveMaximum form for the jsonSchema7 target. The jsonSchema2019-09
target takes the non-draft-7 branch in its number parser and produces
the draft-4 boolean pair (minimum: 0, exclusiveMinimum: true), which
draft 2020-12 rejects. Anthropic's API therefore 400s the entire tool
list whenever dnsProvider-createRecord or updateRecord is included.

Comparing both targets across all 597 generated tools, ignoring the
$schema key this function overwrites, the outputs are byte-identical
except for the two affected tools, which now emit exclusiveMinimum: 0.

Add a regression test sweeping every tool inputSchema for boolean
exclusive bounds, following the existing nested-walk test pattern.

Fixes Dokploy#74
@lorismaz

Copy link
Copy Markdown

Confirmed, this is exactly what broke for me

Reproduced with the repo's pinned versions (zod 3.25.28, zod-to-json-schema 3.25.2): the ttl field comes out as {"type":"integer","exclusiveMinimum":true,"minimum":0,"maximum":9007199254740991} with the current target, and {"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991} with jsonSchema7. A strict model provider rejected the whole tool list every turn because of it.

On the workaround from #74: DOKPLOY_DISABLED_TAGS=dns doesn't filter anything, the tag is dnsProvider. DOKPLOY_DISABLED_TAGS=dnsprovider drops the 11 dnsProvider tools and the rest works fine.

Anything else needed to merge this ?

@1ordo

1ordo commented Aug 19, 2026

Copy link
Copy Markdown
Author

nope should be all, if anyone would like to merge, or let me know and i will work on the edits

@SL-Pirate

SL-Pirate commented Aug 20, 2026

Copy link
Copy Markdown

Confirmed on Dokploy version: v0.30.2

Agent harness: Hermes version: nousresearch/hermes-agent:v2026.6.19

Observation: Sessions fails to load with the error message:

 ┊  Error: HTTP 400: Invalid schema for function 'mcp_dokploy_dnsProvider_createRecord': True is not of type 'number'.               

Please fix

@real-limitless

Copy link
Copy Markdown

Im also having this same exact issue.

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.

Boolean exclusiveMinimum (draft-4 style) in dnsProvider-createRecord/updateRecord — Anthropic API 400s the whole tool list

4 participants