Skip to content

Conversation

@adpare
Copy link
Contributor

@adpare adpare commented Feb 2, 2026

Summary

This PR upgrades Zod to the latest version (4.3.6) and fixes/enables the use of .partial() on our schemas.

This is related to a PR opened on the Workbench REST API: attack-workbench-rest-api

Context

Code:

import { malwareSchema } from "@mitre-attack/attack-data-model";

const partialMalwareSchema = malwareSchema.partial()
partialMalwareSchema.parse(stix);

Throws:

file:///Users/ssica/Development/Sandbox/adm-sandbox/esm/node_modules/zod/v4/core/util.js:435
        throw new Error(".partial() cannot be used on object schemas containing refinements");
              ^

Error: .partial() cannot be used on object schemas containing refinements
    at Module.partial (file:///Users/ssica/Development/Sandbox/adm-sandbox/esm/node_modules/zod/v4/core/util.js:435:15)
    at inst.partial (file:///Users/ssica/Development/Sandbox/adm-sandbox/esm/node_modules/zod/v4/classic/schemas.js:572:38)
    at <anonymous> (/Users/ssica/Development/Sandbox/adm-sandbox/esm/scripts/adm-partial-validation.ts:4:44)
    at ModuleJob.run (node:internal/modules/esm/module_job:271:25)
    at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:578:26)
    at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:116:5)

This change is referenced as a bug fix in the Zod v4.3.0 release notes:

⚠️ .pick() and .omit() disallowed on object schemas containing refinements (colinhacks/zod#5317)
Using .pick() or .omit() on object schemas with refinements now throws an error. Previously, this would silently drop the refinements, leading to unexpected behavior.

const schema = z.object({
  password: z.string(),
  confirmPassword: z.string(),
}).refine(data => data.password === data.confirmPassword);

schema.pick({ password: true });
// 4.2: refinement silently dropped ⚠️
// 4.3: throws error ❌

Migration: The easiest way to migrate is to create a new schema using the shape of the old one.

const newSchema = z.object(schema.shape).pick({ ... })

Though the release note doesn't explicitly mention .partial() -- it only mentions .pick() and .omit() -- this dosubot comment affirms:

when you use .omit(), .partial(), or .exclude() on a schema with refinements (like .refine or .check), the resulting schema does not retain those custom validations. This is by design—these transformation methods change the input type, so the original refinement function may no longer be valid or safe to apply. As explained by @colinhacks, refinements are wiped away to avoid running checks on data shapes that may not match the original intent [https://github.com/colinhacks/zod/issues/2646].

@seansica seansica changed the title Update zod .pick() and .omit() disallowed on object schemas containing refinements Feb 10, 2026
@seansica seansica changed the title .pick() and .omit() disallowed on object schemas containing refinements .pick(), .partial(), and .omit() disallowed on object schemas containing refinements Feb 10, 2026
Upgrade Zod from ^4.0.5 to ^4.3.6 and redesign how schemas handle
.partial(), .pick(), and .omit() — which Zod 4.3+ disallows on schemas
containing refinements.

- Rename extensibleCampaignSchema to campaignBaseSchema and export it,
  giving consumers a refinement-free schema they can derive from
- Extract shared campaignChecks callback to eliminate refinement
  duplication between full and partial schemas
- Remove partial schemas from softwareSchema union to fix zod2md
  generating inline HTML that breaks MDX compilation
- Add schema tiers documentation to principles/schema-design.mdx
- Add new how-to guide for using schema variants (base, full, partial)
@seansica seansica self-assigned this Feb 10, 2026
@seansica seansica merged commit a4166dd into main Feb 10, 2026
4 checks passed
@seansica seansica deleted the update-zod branch February 10, 2026 19:50
@github-actions
Copy link

🎉 This PR is included in version 4.9.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants