21

Troubleshooting

Fix the most common NotForm problems; errors that do not show or clear, ignored config, submit that does nothing, array glitches, and Nuxt auto-import issues.

Find the symptom, read the cause, apply the fix.

Validation and errors

No error appears while I type

Cause. By design. input events do not validate until the field already has an error. A field validates when the user leaves it or commits a value.

Fix. To validate while typing, set validateOn: { input: true } on the field. See Validation.

An error does not clear after I fix the value

Cause. The field is in validationMode: 'lazy' and the event that would clear it is not enabled, or the error is not at this field's exact path.

Fix. Use the default eager mode, or enable the event. Confirm the issue's path matches the field: a field shows only issues at its exact path.

Required fields say "expected string, received undefined"

Cause. The field has no entry in initialValues, so the schema receives undefined and reports its generic type message instead of your custom one.

Fix. Provide '', false, [], or another starting value for every bound field. See Binding inputs.

A cross-field error never shows

Cause. The issue has no path, or the path names a different field. The error is then form-level, or shown by another field.

Fix. Report the issue on the field that should display it. See Cross-field validation.

A form-level error is not displayed anywhere

Cause. FieldError :errors="field" shows only issues at that field's own path. Issues without a path, or on a parent path, are in form.errors.

Fix. Render them from form.errors. See Errors.

A server error disappears when I tab away

Cause. Validating a field replaces the errors at its path. If the schema finds no problem there, the server error is dropped.

Fix. This is intended behavior. See Server errors if you need an error that outlives edits.

isValid is true on a form that is clearly invalid

Cause. isValid means "the error list is empty". Nothing has validated yet.

Fix. Call await form.validate() or submit. See Form state.

Submission

Submitting does nothing

Cause. Validation failed, and the failing field has no visible error. Typical reasons: the field is on another step or is hidden, the issue is form-level, or a required key was never given a value.

Fix. Inspect form.errors:

<template>
  <pre>{{ form.errors }}</pre>
</template>

The second click on submit is ignored

Cause. A submit is already running. Extra submits are ignored until it finishes.

Fix. Disable the button with form.isSubmitting.

My onSubmit data does not match form.values

Cause. onSubmit receives the schema output, and form.values holds the input. Transforms, defaults, and coercions make them differ.

Fix. See Schema input and output.

An error in onSubmit shows nothing in the UI

Cause. Errors thrown by onSubmit are not turned into form errors. They go to Vue's error handler.

Fix. Catch expected failures and call form.setError. See Submission and reset.

The Reset button does not clear the inputs

Cause. Reset restores the baseline, not blank values. Or the button is outside Form, so no handler is attached.

Fix. Keep type="reset" inside <Form>, or call form.reset(). To clear a form that holds loaded data, call form.reset(blankValues) with explicit blank values, such as { name: '', email: '' }, which also makes them the new baseline.

Fields

My field config is ignored

Cause. Fields are cached by path and the config is read on the first call. A call without config, such as one in the template, may have created the field first.

Fix. Create each configured field once, in <script setup>, and reuse that instance. See Validation.

A Vue error says field is a required prop or path is unknown

Cause. You are using v3 syntax, such as <Field path="email">, with v4.

Fix. Pass an instance: <Field :field="form.field('email')">. See the v3 migration guide.

Typing a number gives me a string

Cause. Native inputs produce strings. v-model.number converts, but an empty input produces ''.

Fix. Use v-model.number with a number schema, or keep strings in the form and convert in the schema. See Binding inputs.

field.id breaks my HTML id

Cause. field.id is a symbol for Vue keys, not a string.

Fix. Use field.path for HTML ids and labels.

I get a TypeScript error on form.field('...')

Cause. The path is not in the schema's input shape. Check spelling, nesting, and whether the key is optional or renamed by a transform.

Fix. See TypeScript. The error is NotForm telling you the path does not exist.

Array fields

Items lose focus or show the wrong state after reordering

Cause. The list is keyed by index.

Fix. Key by item.id. See Array fields.

Errors or touched state land on the wrong item

Cause. The array was changed with push, splice, or sort on form.values instead of the array methods.

Fix. Use append, insert, remove, move, swap, and update.

Removing the last item leaves an error

Cause. The array's schema rule, such as .min(1), reports an issue on the array's own path.

Fix. That is intended. Show it with <FieldError :errors="arrayField" />.

Nuxt

Components or useForm are not found

Cause. The module is not registered, or the dev server was not restarted, or another component or composable has the same name.

Fix. Check modules: ['@notform/nuxt'], restart, and add an alias if there is a conflict. See Nuxt module.

I cannot import types from notform

Cause. Strict package managers do not expose a module's own dependencies.

Fix. Add notform as a direct dependency.

Performance

Validation feels slow, or my API is called too often

Cause. Each field validation runs the whole schema, including any async rules.

Fix. Add a debounce to the field that owns the slow rule, and cache lookups. See Async validation.

Still stuck?

Open an issue on the NotForm repository. Include your schema, the form setup, and the behavior you see.

Copyright © 2026 NotForm
Published under MIT License