Skip to content

Bump zod from 3.25.76 to 4.5.4 - #35

Merged
antonisobkowicz-asana merged 5 commits into
mainfrom
dependabot/npm_and_yarn/zod-4.5.4
Sep 7, 2026
Merged

Bump zod from 3.25.76 to 4.5.4#35
antonisobkowicz-asana merged 5 commits into
mainfrom
dependabot/npm_and_yarn/zod-4.5.4

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Sep 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Dependabot's mechanical bump alone didn't compile — zod v4 has real breaking changes this codebase relied on. Fixed all of them:

  • z.record() signature change: now requires an explicit key schema (z.record(z.string(), z.unknown())), not just the value schema.
  • z.ZodTypeAny's inferred output tightened from any to unknown, surfacing two latent typing gaps zod v3 had silently papered over:
    • singleObjectEnvelope<T> and a duplicated z.object({ data: schema }).parse(...).data pattern across 6 test files couldn't statically resolve .data on a generic schema's parsed output. Consolidated the test-side duplication into one parseEnvelopeData helper; gave singleObjectEnvelope an explicit, cast-backed return type. Runtime behavior unchanged.
    • mutationVariantsToSchemas returned z.ZodTypeAny for both schemas, so every mutation tool's parsed output was effectively any — none of its status/outcome/data union members were ever type-checked. Made it generic over the variant tuple so callers get the real discriminated union back. This caught a genuine pre-existing bug in workflow.ts: addDependency/removeDependency shared one implementation typed to return the union of both outcomes, silently assignable to each specific one only because of the any leak.
  • .describe(X).optional() (and .nullable()/.nullish()) silently drops the description entirely under zod v4 — no type error, no runtime error, just an undocumented field. This affected 28 fields across ticket_inputs.ts, comments.ts, and tools/tickets.ts — real descriptions in the public MCP tool schemas that agents read to know how to call these tools. Only 2 of the 28 had test coverage that happened to catch it. Reordered every affected chain to .optional().describe(...) (verified via a full-codebase scan) and added a permanent regression test (tests/zod_describe_order.test.ts) that scans src/ for this ordering, since the bug is silent at both the type and runtime level — verified the test actually catches the pattern before relying on it.

Test plan

  • npm run typecheck
  • npm run lint
  • npm test (371 tests passing, including the new describe-order regression test)
  • npm run build
  • CI green on this branch

@dependabot dependabot Bot added dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code labels Sep 4, 2026
Bumps [zod](https://github.com/colinhacks/zod) from 3.25.76 to 4.5.4.
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](colinhacks/zod@v3.25.76...v4.5.4)

---
updated-dependencies:
- dependency-name: zod
  dependency-version: 4.5.4
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot
dependabot Bot force-pushed the dependabot/npm_and_yarn/zod-4.5.4 branch from 92e2639 to 887ce24 Compare September 7, 2026 10:27
zod v4 requires z.record(keySchema, valueSchema); the single-argument
form used for the error-details bag no longer compiles.
zod v4 tightened z.ZodTypeAny's inferred output from any to unknown,
which surfaced two latent typing gaps that zod v3 had been silently
papering over:

- singleObjectEnvelope<T> and the test suite's duplicated
  z.object({ data: schema }).parse(...).data pattern couldn't
  statically resolve `.data` on a generic schema's parsed output.
  Consolidated the test-side duplication into one parseEnvelopeData
  helper and gave singleObjectEnvelope an explicit cast-backed return
  type; both keep the runtime behavior identical.
- mutationVariantsToSchemas returned z.ZodTypeAny for both schemas,
  so every mutation tool's parsed output was effectively `any` and
  none of its status/outcome/data union members were ever checked.
  Made it generic over the variant tuple so callers get the real
  discriminated union back. This caught a genuine pre-existing bug in
  workflow.ts: addDependency/removeDependency shared one
  implementation typed to return the union of both outcomes, silently
  assignable to each specific one only because of the `any` leak.
…le wrappers

Under zod v4, .describe(X).optional() (and .nullable()/.nullish())
silently drops the description entirely instead of erroring — the
wrapper doesn't forward it. This affected 28 fields across
ticket_inputs.ts, comments.ts, and tools/tickets.ts, all part of the
public MCP tool schemas shown to calling agents, and only 2 of the 28
had test coverage that happened to catch it.

Reordered every affected chain to .optional().describe(...) (verified
via a full-codebase scan). Added a permanent regression test that
scans src/ for the dangerous ordering, since this class of bug is
silent at both the type and runtime level.
@antonisobkowicz-asana
antonisobkowicz-asana merged commit c6ff592 into main Sep 7, 2026
2 checks passed
@antonisobkowicz-asana
antonisobkowicz-asana deleted the dependabot/npm_and_yarn/zod-4.5.4 branch September 7, 2026 12:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code

Development

Successfully merging this pull request may close these issues.

1 participant