arrayFieldToInputSchema
arrayFieldToInputSchema<
TArrayType,TFieldMeta>(props):ZodType
Defined in: packages/core/src/fields/array/inputSchema.ts:92
Builds a Zod schema for validating an array field value in the admin form.
Wraps the nested item schema (built recursively via adminFieldToInputSchema)
in z.array(…), then composes min/max item-count constraints onto the
same chain built for required, rather than reassigning over it — a
required field with min/max configured keeps every check. Required
fields attach { error: "This field is required." } to the base
z.array() call and add .min(1, "This field is required."), replacing
the previous dead superRefine (it only ever checked for undefined/
null, which the previously-unconditional .default() had already
substituted away before the refine ran, and it never checked emptiness at
all) (CORE-1). Required fields never receive .default(); non-required
fields keep .default(field.defaultValue ?? []).
min/max are independent of required, but only skip an empty array
when the field is optional: an optional field’s empty/omitted value
shouldn’t fail its own min, but a required field’s empty value is
already invalid (via .min(1, requiredError) above), so its configured
min/max still runs on [] too — otherwise a required field’s own
custom min/max error message could never surface (an empty array is
the only way to violate a min in the first place) and only the generic
“This field is required.” would ever show. A non-empty array — required
or not — is always checked against a configured min/max.
When props.data is given AND field.items (or anything nested in it)
declares a condition, each array ITEM needs its own siblingData —
unlike a group’s sub-fields, items are positional, not keyed, so there
is no single data[key] to compute up front at schema-build time
(Step 9). The base/outer item schema is built loose (z.unknown())
instead of the real item schema — enforcing required up front there
would reject a condition-hidden field before the real, condition-aware
per-item re-parse ever runs — and a superRefine re-parses every actual
item against a fresh
adminFieldToInputSchema({ field: field.items, data, siblingData: item })
— item IS the new siblingData, since an array item’s resolved value
has no extra key to index through, mirroring how adminFieldToInputSchema
already treats a missing key for item dispatch. Issues from that
re-parse are re-added through ctx.addIssue with the item’s index
prepended to the path, so a failure still names the right item/field for
the admin form. Without conditions anywhere in field.items, the item
schema stays exactly what it was — a single
adminFieldToInputSchema({ field: field.items, ignoreRequired }) call,
no superRefine, no added cost.
An object-shaped item (field.items.type === "group") additionally gets
id: z.string().optional() intersected onto its schema (withItemId,
below) — optional because an existing document predating this step may
have items with no id yet (same reasoning as the Convex validator,
array/validator.ts); prepareEdit’s assignArrayItemIds backfills one
on every write regardless, so the client form never actually submits an
id-less object item. .and(...), not groupFieldToInputSchema taking an
extra parameter, because a group() used OUTSIDE an array must never gain
an id slot — this intersection is scoped to array ITEMS only.
Type Parameters
Section titled “Type Parameters”TArrayType
Section titled “TArrayType”TArrayType extends ArrayType = string
TFieldMeta
Section titled “TFieldMeta”TFieldMeta extends object = { }
Parameters
Section titled “Parameters”Input props.
Record<string, unknown>
The full top-level document. Omitted skips condition evaluation for this array’s items entirely (today’s behavior).
ArrayField<string, TArrayType, TFieldMeta>
The resolved array field definition
ignoreRequired?
Section titled “ignoreRequired?”boolean
Forwarded to the recursive
adminFieldToInputSchema({ field: field.items }) call so a draft-lenient
pass (getFieldsInputSchema’s ignoreRequired) reaches every item, not
just this array’s own required check.
Returns
Section titled “Returns”ZodType
A Zod array schema with item count constraints and optionality applied
Examples
Section titled “Examples”const field = array({ items: text(), required: true })arrayFieldToInputSchema({ field })// → z.array(z.string(), { error: "This field is required." }).min(1, "This field is required.")// Optional field, min/max still enforced once a value is suppliedconst field = array({ items: number(), min: 2, max: 5 })const schema = arrayFieldToInputSchema({ field })schema.safeParse(undefined) // → success: [] (skips min/max — empty)schema.safeParse([1]) // → fails: below minschema.safeParse([1, 2]) // → success