Skip to main content

Optional Field Control

Configure how optional Prisma fields are validated using different Zod patterns.

This recipe walks through the three behaviours from the request/response angle — pick one by the shape of payload you want to accept. For the option reference, the generated-output examples and the object-schema carve-out, see Optional Field Behavior.

Scope

optionalFieldBehavior applies to pure model schemas (generated/schemas/models/<Model>.schema.ts) and to array-based custom variants. The objects/ input schemas and the object-based variants/ files use their own fixed policies and do not read this setting — see Object Schemas: Optional vs Nullable.

Every example below therefore assumes pure models are being emitted, which is set in the JSON config ("pureModels": true) — there is no generator-block flag for it.

Use Cases

API with Null Values

When your API accepts explicit null values alongside undefined/omitted fields:

generator zod {
provider = "prisma-zod-generator"
optionalFieldBehavior = "nullish" // default
}

model User {
id Int @id
name String?
bio String?
}

The generated UserSchema accepts all these patterns:

// All valid
{ id: 1, name: "John", bio: "Developer" }
{ id: 1, name: null, bio: undefined }
{ id: 1 } // name and bio omitted

Strict No-Null API

When you want to reject explicit null values:

generator zod {
provider = "prisma-zod-generator"
optionalFieldBehavior = "optional"
}

Generated validation:

// Valid
{ id: 1, name: "John" }
{ id: 1 } // name omitted

// Invalid - null rejected
{ id: 1, name: null } // ❌ Validation error

Always-Present Fields

When optional fields must always be included in requests:

generator zod {
provider = "prisma-zod-generator"
optionalFieldBehavior = "nullable"
}

Generated validation:

// Valid
{ id: 1, name: "John", bio: "Developer" }
{ id: 1, name: null, bio: null }

// Invalid - fields must be present
{ id: 1 } // ❌ Missing name and bio

Configuration Options

Generator Block

generator zod {
provider = "prisma-zod-generator"
optionalFieldBehavior = "nullish" // or "optional" | "nullable"
}

JSON Config

zod-generator.config.json
{
"optionalFieldBehavior": "nullish"
}

Comparison Table

BehaviorZod OutputAccepts undefinedAccepts nullAllows Omitted
nullish.nullish()
optional.optional()
nullable.nullable()

Migration Example

Changing from the legacy .optional().nullable() pattern:

Before:

// Legacy behavior (equivalent to nullish)
name: z.string().optional().nullable();

After with explicit configuration:

// With optionalFieldBehavior = "nullish"
name: z.string().nullish();

// With optionalFieldBehavior = "optional"
name: z.string().optional();

// With optionalFieldBehavior = "nullable"
name: z.string().nullable();

Choosing a behaviour for Prisma-shaped payloads

Prisma's own input types allow null for optional fields, so a payload that carries an explicit null only round-trips through the pure model schema under nullish or nullable:

import { UserSchema } from './generated/schemas/models/User.schema';

// With optionalFieldBehavior = "nullish" or "nullable"
UserSchema.parse({ id: 1, name: null }); // ✅

// With optionalFieldBehavior = "optional"
UserSchema.parse({ id: 1, name: null }); // ❌ null is rejected — omit the key instead
UserSchema.parse({ id: 1 }); // ✅

Pick optional only when your clients omit fields rather than sending null. The objects/ input schemas are unaffected either way: UserCreateInputObjectSchema and friends always emit .optional().nullable() for optional non-relation fields, so they keep accepting both.

The optionalFieldBehavior setting controls how Prisma optional fields (like String?) are handled. For making all fields optional in specific variants, use the partial flag in variants configuration:

zod-generator.config.json
{
"optionalFieldBehavior": "optional",
"variants": {
"input": {
"enabled": true,
"partial": true
}
}
}

Key differences:

  • optionalFieldBehavior: Controls only Prisma optional fields (String?), in pure model schemas
  • partial flag: Makes ALL fields optional in the variant it is set on