Skip to content

nav-invalid

{ ok: false, reason: 'invalid', code: 'nav-invalid', by: '<step>', errors: { <field>: '<message>' }, url: '…/errors/nav-invalid' }

Returned, not thrown, by next() and go(). The wizard stays where it was, and the same errors are committed to state under the step’s id, so useErrors() renders them without reading the result.

Before a forward move leaves a step, the engine runs that step’s validate. A validator that returns field messages refuses the move, and by names the step it ran on. go() validates too, force: true included: force skips the navigation policy and nothing else. back() never validates.

A repeat group refuses the same way when its items cannot be told apart. Then by is the group, and the message sits under the keyBy field; repeat-keys explains it.

This is usually the wizard working as intended: the user has not filled the field yet. Render errors beside the fields they name, as Render field errors does. To move without validating on purpose - a “save and continue later” button - pass { validate: false } to that one call.