Skip to content

Zod refine errors with specific paths aren't propagated to field error states #1633

@DOdrums

Description

@DOdrums

Description

When using Zod's refine method with a specific path for error reporting, TanStack React Form correctly adds the error to the form's overall error state, but doesn't propagate it to the individual field's error state. This creates a situation where errors exist in the form but aren't automatically displayed in the UI without manual intervention.

Environment

  • Integration: React Router 7.6.2
  • React: 19.0.0
  • Zod: 3.25.32

Steps to reproduce

Reproduction Steps

  1. Define a Zod schema with a refine validation that includes a specific field path:
const schema = z.object({
  active_from: z.string(),
  active_until: z.string(),
})
.refine(
  (data) => {
    const fromDate = new Date(data.active_from);
    const untilDate = new Date(data.active_until);
    return fromDate <= untilDate;
  },
  {
    error: 'End date must be after start date',
    path: ['active_until'], // Specifies which field should receive the error
  }
);
  1. Set up a form with TanStack React Form and server validation:
// Server validation function
export const serverValidate = createServerValidate({
  onServerValidate: schema,
});

// In component
const actionData = useActionData();

const form = useForm({
  defaultValues: { ... },
  transform: useTransform(
    (baseForm) => {
      return mergeForm(baseForm, actionData ?? {});
    },
    [actionData],
  ),
});
  1. Render fields including an error display component:
<form.Field name="active_until">
  {(field) => (
    <div>
      <DatePicker
        value={field.state.value}
        onChange={(value) => field.handleChange(value)}
      />
      {field.state.meta.errors?.length ? (
        <FieldError field={field} />
      ) : null}
    </div>
  )}
</form.Field>

Expected Behavior

When the form is submitted and validation fails with a refine error targeting the active_until field, that error should automatically appear in field.store.state.meta.errors for the active_until field.

Actual Behavior

The error correctly appears in:

  • form.state.errors[0].active_until
  • actionData.errors[0].active_until

But does NOT appear in:

  • form.fieldInfo.active_until.instance.store.state.meta.errors

This means that even though the error exists in the form state, it doesn't propagate to the field's own error state, so UI components that rely on field.state.meta.errors don't display the error.

Feature Request

Ensure that errors from Zod's refine method with a specified path automatically propagate to the respective field's error state.

How often does this bug happen?

Every time

Platform

  • OS: Windows
  • Browser: Google Chrome

TanStack Form adapter

None

TanStack Form version

v1.12.0

TypeScript version

v5.7.3

Additional Context

This issue specifically affects validation rules that compare multiple fields (cross-field validation) where the error should be displayed on a specific field. The refine method in Zod is the recommended way to handle this type of validation, and it works correctly with the path option at the form level, but the error doesn't reach the field component in TanStack React Form.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions