Forms Should Help, Not Just Complain: Form Validation for Vibe Projects
The most common AI-generated form problem is not ugly styling but validation that is too lax or too strict. This guide covers six principles: help users get it right, keep three rule locations consistent, time errors well, write plain-language messages, guard rules with tests, and handle multi-step saving — plus a pre-launch checklist.

Scope: what this guide covers, and what it does not
Forms are where vibe projects are easiest for AI to generate — and easiest for users to hate. A sign-up form, a publish form, a checkout form: on the surface just a few input boxes, but underneath a whole set of judgments: what counts as correct, when to warn, how to word the warning, whether a mistake can be fixed without redoing the whole form. The most common AI-generated form problems are not ugly styling. They are validation logic that is either too lax (anything passes, dirty data goes straight into the database) or too strict (errors everywhere, users abandon the form halfway). This guide covers that work: how to set rules per field, when errors should appear, how to write error messages, how frontend and backend validation should divide the labor, and how to protect the rules with tests.
First, the boundaries, so this guide does not blur into neighboring guides already on the site. The error-and-empty-states guide covers error interfaces in general; this guide focuses only on the validation timing and wording of the form scenario. The login-devices-and-sessions guide covers session security after login and is not repeated here. The file-upload guide covers size and format limits for uploads; this guide touches it only where a file field is also a form field, and does not expand the upload pipeline. The example product "Qinghe Ledger" (a fictional personal bookkeeping app) and the person "A-Zhe" (a fictional solo developer) are invented for illustration, and the code fragments are illustrative, explaining rules and division of labor rather than recommending any framework's official approach.
First principle: validation helps users get it right, not catch them getting it wrong
Before building form validation, get the mindset right: its purpose is to let users submit correct data with the least effort, not to prove they made mistakes. That mindset drives many small decisions. Take a phone-number field: should it accept only exactly 11 digits, or also accept spaces and dashes and clean them up in code? From a "catch mistakes" mindset, you write a "format incorrect" error. From a "help get it right" mindset, you first strip spaces and dashes and only complain if it still fails. The same applies to an amount field: accept only "12.50," or also accept "12.5" and "¥12.50" and normalize in code? Every reasonable format you accept is one fewer interruption for the user.
This principle has a corollary: do not ask users to fill in what they do not need to fill in. Fields with fixed options — country, city, currency — should be selectors, not free text. Dates should use a date picker, not force users to guess between "2026/10/30" and "30-10-2026." Fields that can be derived from existing data (such as defaulting a region from a phone number's area) should be prefilled and editable. The easiest mistake AI makes when generating forms is turning every field into a free-text box and then piling validation rules on top to clean up the mess free text creates. Narrow the input method first, and the validation work halves.
Second principle: rules live in three places, and all three must agree
A form's validation rules actually live in three places: frontend instant validation, backend final validation, and database or business-layer constraints. All three must agree, or they will fight at some point: the frontend says yes and the backend says no, and the user sees "everything looked right but submission failed" — the most infuriating experience there is. Or the frontend blocks something the backend allows, and a knowledgeable user bypasses the frontend, calls the API directly, and dirty data enters the database. So the correct division is: frontend validation serves experience (warn early, interrupt rarely), backend validation serves security (final arbiter, trusting nothing the frontend sends), and database constraints serve as the backstop (uniqueness, non-null, foreign keys).
The most practical way to land this is a field list: one row per field stating its name, type, required or not, length and format, value range, uniqueness, and error message. That list is the shared source for frontend, backend, and tests alike; when a rule changes, update the list first, then sync it to all three code locations. The list must also state boundary values explicitly: if a username must be 2 to 20 characters, what should happen at 1, 2, 20, and 21 characters, with test cases written for exactly those four boundaries. Many validation bugs are not wrong rules but unstated boundaries: the frontend writes "under 20" while the backend writes "20 or under," and one character's difference becomes a production issue.
One class of rules is especially prone to frontend-backend drift: rules that require a database lookup, such as whether a username is taken, whether a coupon is valid, or whether stock remains. The frontend can only offer an advisory check here (for example, an async lookup after input, warning early that there may be a problem); the final answer must come from the backend check at submit time, and the copy for "someone grabbed it just before you submitted" must be prepared in advance. What users cannot accept is not "this name is taken." It is "it said available a moment ago, now it says taken at submit, and nobody explains why."
Third principle: when an error appears matters more than the error itself
The same error message feels completely different depending on when it shows. Form validation timing usually comes in four flavors: live validation while typing, validation on blur, validation of everything at submit, and server-side validation returned after submit. No single timing fits all cases; the right approach mixes them by field type. Format rules (does an email contain @, how many digits does a phone number have) suit blur-time warnings: telling users right after they finish a field, before moving to the next, is far friendlier than dumping ten errors at submit. Live validation should be used sparingly: flagging "format incorrect" after the first keystroke interrupts users before they have finished writing, which is worse than no validation. Live validation fits only two cases: password strength, where users need to adjust as they type, and character counts, which are pure hints rather than errors.
Submit-time validation is still necessary, because some users skip fields or autofill the whole form at once. Submit-time error handling must do three things: scroll the page to the first error field and focus it, so users do not have to hunt; show a summary listing only how many problems there are and in which fields, without repeating every error message at the top; and preserve everything already filled in correctly, so users only fix the wrong fields instead of redoing the whole form. That third item is the one AI-generated forms most often drop: many of them clear the entire form on a failed submit, wiping ten minutes of user input in one second. That experience loses users faster than any wording problem.
One more timing detail: never show errors on fields the user has not touched. Many forms open with a screen full of red, because validation ran across the board on page load. The correct rule is "touched, then validate": only fields the user has visited, or fields after a submit attempt, show their error state. This small rule decides a user's first impression of the form: "a form waiting for me to fill it in" versus "a form already accusing me."
Fourth principle: error messages must speak plainly, point at the spot, and say how to fix it
Error copy has three tests, and failing any one of them means it is not good enough. First, speak plainly: never write developer-only phrases such as "invalid input," "parameter error," or "validation failed." Write "the phone number should be 11 digits" or "the password needs at least 8 characters, including letters and numbers." Second, point at the spot: the message must sit next to its field, and the field itself must carry a visual marker (a colored border, an icon), not just a line at the top of the page saying "the form has errors" while users guess which field. Third, say how to fix it: do not just say what is wrong, say what right looks like — "this username is taken; try 'A-Zhe 2026' or pick another name" or "the end date cannot be earlier than the start date; please check both dates."
Copy should also avoid two extremes. One is over-technical: "regular expression mismatch" or "field length exceeds constraint" tells users nothing actionable. The other is over-vague: "please check your input" or "something went wrong" uses words users understand but still leaves them unsure what to change. The test is simple: show the error screenshot to a friend who did not build the feature and ask "do you know what to change, and to what?" If they cannot answer, the copy fails. And never blame the user in copy: replace "you entered it wrong" or "you forgot to fill this in" with neutral phrasing such as "this field still needs to be filled in" or "11 digits are needed here." That small tone difference matters more to how users feel than most teams expect.
Password fields deserve a separate note. The most common anti-pattern is listing all password rules at once (length, upper and lower case, digits, special characters) so users discover a new requirement with every correction. A better approach is a checklist that ticks off live: each satisfied rule gets a tick, and users can see at a glance what remains. The confirmation field should also be compared on blur, not only at submit, saving many "submit failed because the two entries differ" frustrations. And never reveal extra information in password errors, such as hinting at what the old password was.
Fifth principle: protect the rules with tests, not by clicking through manually every time
Once a form has more than ten fields, manually clicking through before every release stops being realistic, and tests must take over. Form validation test cases can be generated from a fixed table: for each field, four case types — valid value, boundary value, invalid value, empty value — plus three cross-field types: dependencies between fields (end date after start date), rules requiring a database lookup (username taken), and preservation of already-filled data after a failed submit. Once that table is written, writing the test code is mostly filling in the blanks, and AI-generated test cases can follow the same table instead of improvising freely.
Two categories are easiest to miss in tests and worth calling out separately. The first is autofill and paste: browser autofill, password-manager fills, and pasted content (often carrying extra spaces or newlines) can behave completely differently from typed input under validation, and should be tested by hand at least once before launch. The second is network failure and double submission: the submit button must disable immediately once a request is in flight, preventing double submissions from impatient clicks; and a network failure must tell users clearly "this was not submitted, please try again," rather than leaving them guessing whether it went through. Double submission in payment and registration forms is a real-money problem and deserves its own line in the checklist.
Finally, there is the accessibility dimension AI-generated forms most often ignore: error information must not rely on color alone (red text is unhelpful to color-blind users) and must include text and icons together; error fields must be readable by screen readers, with messages programmatically associated with their fields rather than merely placed visually nearby; and keyboard users must be able to tab to every error field. These are not bonus points. They are the baseline for whether a form is usable by everyone. Walking the whole form by keyboard once, and listening to the error messages through a screen reader once, takes under half an hour and blocks an entire class of user complaints.
Sixth principle: multi-step forms must let users go back and must save progress
When a form grows long, it is often split into steps: basics, details, confirmation. For multi-step forms, validation should be sliced by step: the current step validates only its own fields, and users should not be blocked from advancing by fields in later steps they have not reached; but equally, validation must not wait until the final step to check everything at once, forcing users to page back through the whole flow to fix things. The better pattern is: validate each step on advancing, let users go back and edit earlier steps at any time, and if an earlier edit affects later steps (for example, changing a region changes the available service list), tell users explicitly that "the earlier change affects later options, please check" instead of silently clearing later choices.
Multi-step forms also need one non-negotiable feature: saving progress midway. A user on step three whose browser crashes, whose phone dies, or who gets interrupted by a call, and who returns to find step one waiting again, is almost certainly lost. Saving can be lightweight: store completed steps locally, and on return ask "we found an unsubmitted draft; continue?" rather than restoring without asking. Local saving has a privacy boundary: for steps involving identity documents or bank cards, prefer not to save, or save only the non-sensitive parts. Security beats convenience there, and that trade-off should be stated to users rather than decided silently for them.
Pre-launch checklist
Go through this list before launch: the field list is written, and frontend, backend, and database rules agree, with boundary values explicit; input methods are narrowed — fixed options use selectors, derivable fields are prefilled; validation timing is mixed — format rules warn on blur, password rules hint live, submit-time validation locates the first error field automatically; untouched fields show no errors; failed submits preserve correctly filled fields; every error message passes the three tests of plain language, pointing at the spot, and saying how to fix it; database-dependent rules defer to the backend check at submit, with copy ready for "just taken" cases; the submit button guards against double clicks, and network failures get an explicit message; autofill and paste paths have been tested by hand; test cases cover valid, boundary, invalid, and empty values per field plus cross-field dependencies; error messages do not rely on color alone, include text and icons, and are reachable by keyboard and screen reader. Any missing item on this list will come back at the moment a user first fills the form seriously — in the form of churn.
Comments (0)
Related articles

Once user-generated content goes live, moderation is a day-one job. This guide gives a solo team an executable method: a one-page standard, four handling tiers, a four-layer funnel, an appeals process, a half-hour daily rhythm, and defenses against report abuse. Examples are fictional.

Help docs and long announcements take days to write, yet readers leave in under a minute. Usually the problem is not the content but the reading experience: cramped type, no way to find a section, no way to resume. This guide covers findability, pausing, resuming and readability, plus a twelve-item launch checklist.

Waiting hurts mostly because of uncertainty, not time. This guide covers skeleton screens vs spinners vs progress bars, the missing 'submitting' button state, background processing, optimistic updates, upload progress, and timeout handling.