[{"data":1,"prerenderedAt":1304},["ShallowReactive",2],{"content-\u002Fdocs\u002Ftroubleshooting":3},{"id":4,"title":5,"body":6,"description":16,"extension":1298,"meta":1299,"navigation":223,"path":1300,"seo":1301,"stem":1302,"__hash__":1303},"docs\u002Fdocs\u002Ftroubleshooting.md","Troubleshooting",{"type":7,"value":8,"toc":1272},"minimark",[9,13,17,22,25,37,61,83,87,106,137,157,161,168,262,265,272,280,283,287,290,317,329,332,363,370,381,522,526,556,563,693,709,713,720,773,785,789,800,803,816,823,831,850,883,890,896,923,943,946,954,974,978,996,1018,1033,1037,1047,1051,1065,1082,1089,1104,1193,1209,1213,1232,1247,1253,1257,1268],[10,11,5],"h1",{"id":12},"troubleshooting",[14,15,16],"p",{},"Common issues — symptom first, fix second.",[18,19,21],"h2",{"id":20},"my-field-doesnt-validate","\"My field doesn't validate\"",[14,23,24],{},"Three independent causes.",[14,26,27,31,32,36],{},[28,29,30],"strong",{},"The schema doesn't include the field."," An ",[33,34,35],"code",{},".optional()"," wrapper\nwithout an inner refinement accepts anything. Double-check the\nschema is what you think it is.",[14,38,39,50,51,53,54,56,57,60],{},[28,40,41,42,45,46,49],{},"You're in ",[33,43,44],{},"strict: false"," and watching ",[33,47,48],{},"validate()","."," Lax mode\nstrips refinements during default-values derivation so the form\nmounts with empty values without failing. Refinements re-apply on\nsubmit. If you want ",[33,52,48],{}," to fire refinements immediately,\ndrop the ",[33,55,44],{}," opt-out — ",[33,58,59],{},"strict: true"," is the default.",[14,62,63,66,67,70,71,74,75,78,79,82],{},[28,64,65],{},"The path doesn't match the schema."," ",[33,68,69],{},"'items.0.name'"," and\n",[33,72,73],{},"['items', 0, 'name']"," canonicalise to the same path. But\n",[33,76,77],{},"['items', '0', 'name']"," (string ",[33,80,81],{},"'0'",") does NOT — emit numbers\nwhen the position is an array index.",[18,84,86],{"id":85},"hydration-mismatch-after-ssr","\"Hydration mismatch after SSR\"",[14,88,89,100,101,49],{},[28,90,91,92,95,96,99],{},"Did you call ",[33,93,94],{},"hydrateAttaformState(app, payload)"," before\n",[33,97,98],{},"app.mount(...)","?"," It has to land before setup runs. See the\n",[102,103,105],"a",{"href":104},".\u002Frecipes\u002Fssr-hydration","SSR recipe",[14,107,108,66,111,114,115,114,118,114,121,124,125,128,129,132,133,136],{},[28,109,110],{},"Non-JSON-safe value in the form?",[33,112,113],{},"Date",", ",[33,116,117],{},"Map",[33,119,120],{},"Set",[33,122,123],{},"BigInt",",\nand circular refs don't survive ",[33,126,127],{},"JSON.stringify",". Either coerce at\nthe form boundary (",[33,130,131],{},"z.date().transform((d) => d.toISOString())",")\nor use Nuxt's ",[33,134,135],{},"devalue","-based payload (automatic under Nuxt).",[14,138,139,145,146,149,150,153,154,156],{},[28,140,141,144],{},[33,142,143],{},"escapeForInlineScript"," missing on the bare-Vue side?"," A form\nvalue containing ",[33,147,148],{},"\u003C\u002Fscript>"," breaks the inline payload. Wrap your\n",[33,151,152],{},"JSON.stringify(payload)"," in ",[33,155,143],{},". Not required\nunder Nuxt.",[18,158,160],{"id":159},"form-from-another-page-leaked-state-in","\"Form from another page leaked state in\"",[14,162,163,164,167],{},"Two components mounted the same ",[33,165,166],{},"key"," at the same time. Use unique,\nstable string literals — not generated values:",[169,170,175],"pre",{"className":171,"code":172,"language":173,"meta":174,"style":174},"language-ts shiki shiki-themes github-light github-dark","\u002F\u002F Bad — collides when both instances live.\nuseForm({ schema, key: `form-${Math.random()}` })\n\n\u002F\u002F Good — stable per purpose.\nconst signupFormKey = 'signup' as const\nuseForm({ schema, key: signupFormKey })\n","ts","",[33,176,177,186,218,225,231,254],{"__ignoreMap":174},[178,179,182],"span",{"class":180,"line":181},"line",1,[178,183,185],{"class":184},"sJ8bj","\u002F\u002F Bad — collides when both instances live.\n",[178,187,189,193,197,201,204,206,209,212,215],{"class":180,"line":188},2,[178,190,192],{"class":191},"sScJk","useForm",[178,194,196],{"class":195},"sVt8B","({ schema, key: ",[178,198,200],{"class":199},"sZZnC","`form-${",[178,202,203],{"class":195},"Math",[178,205,49],{"class":199},[178,207,208],{"class":191},"random",[178,210,211],{"class":199},"()",[178,213,214],{"class":199},"}`",[178,216,217],{"class":195}," })\n",[178,219,221],{"class":180,"line":220},3,[178,222,224],{"emptyLinePlaceholder":223},true,"\n",[178,226,228],{"class":180,"line":227},4,[178,229,230],{"class":184},"\u002F\u002F Good — stable per purpose.\n",[178,232,234,238,242,245,248,251],{"class":180,"line":233},5,[178,235,237],{"class":236},"szBVR","const",[178,239,241],{"class":240},"sj4cs"," signupFormKey",[178,243,244],{"class":236}," =",[178,246,247],{"class":199}," 'signup'",[178,249,250],{"class":236}," as",[178,252,253],{"class":236}," const\n",[178,255,257,259],{"class":180,"line":256},6,[178,258,192],{"class":191},[178,260,261],{"class":195},"({ schema, key: signupFormKey })\n",[14,263,264],{},"Mount \u002F unmount cycles are handled automatically — keys only\ncollide when two forms with the same key live concurrently.",[14,266,267,268,271],{},"In dev, a collision whose schemas disagree on shape surfaces as\na ",[33,269,270],{},"console.warn",":",[169,273,278],{"className":274,"code":276,"language":277},[275],"language-text","[attaform] Two useForm() calls with key \"signup\" use\nstructurally-different schemas. Only the first caller wires the\nform; the second caller's schema is silently ignored (shared\n\"last-write\" semantics). …\n  existing schema fingerprint: …\n  incoming schema fingerprint: …\n","text",[33,279,276],{"__ignoreMap":174},[14,281,282],{},"If the sharing is intentional (both sites genuinely want the same\nstore), pass the same schema to both. If it's accidental, give\none of them a unique key. The warning is dev-only and never fires\nin production builds.",[18,284,286],{"id":285},"shared-key-warning-fires-for-schemas-i-think-are-identical","\"Shared-key warning fires for schemas I think are identical\"",[14,288,289],{},"The fingerprint is a best-effort structural hash. Two known\nfalse-positive sources in custom adapters:",[291,292,293,301],"ul",{},[294,295,296,297,300],"li",{},"The adapter's ",[33,298,299],{},"fingerprint()"," builds a string whose contents\ndepend on a non-deterministic input (e.g. a factory default\ngetter that allocates a new value on every call). Make the\nfactory path collapse to an opaque sentinel.",[294,302,303,304,307,308,114,310,114,313,316],{},"Two declarations look identical in source but one has a\nrefinement the other doesn't. Refinements in the Zod adapters\nintentionally collapse to ",[33,305,306],{},"fn:*"," so most refinement-only\ndeltas don't fire the warning, but shape deltas (wrapping\nwith ",[33,309,35],{},[33,311,312],{},".default(…)",[33,314,315],{},".catch(…)",") do.",[18,318,320,321,324,325,328],{"id":319},"registeremail-returns-a-never-typed-value","\"",[33,322,323],{},"register('email')"," returns a ",[33,326,327],{},"never","-typed value\"",[14,330,331],{},"The schema generic couldn't be inferred. Two likely causes:",[291,333,334,345],{},[294,335,336,337,340,341,344],{},"Your schema is typed as bare ",[33,338,339],{},"ZodObject"," without its concrete\nshape. Use the literal (",[33,342,343],{},"z.object({ email: z.string() })",") or\ngive the variable a precise type.",[294,346,347,348,350,351,354,355,358,359,362],{},"You imported ",[33,349,192],{}," from ",[33,352,353],{},"attaform"," (the abstract\nentry) but passed a zod schema directly. Import from\n",[33,356,357],{},"attaform\u002Fzod"," or ",[33,360,361],{},"\u002Fzod-v3"," instead.",[18,364,320,366,369],{"id":365},"handlesubmit-doesnt-run-when-i-submit-the-form",[33,367,368],{},"handleSubmit"," doesn't run when I submit the form\"",[14,371,372,373,376,377,380],{},"As of 0.7, ",[33,374,375],{},"handleSubmit(onSubmit)"," returns the ",[28,378,379],{},"handler function",",\nnot a Promise. Bind the returned value:",[169,382,386],{"className":383,"code":384,"language":385,"meta":174,"style":174},"language-vue shiki shiki-themes github-light github-dark","\u003Cscript setup lang=\"ts\">\n  const submit = handleSubmit(async (values) => {\n    await api.signup(values)\n  })\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cform @submit.prevent=\"submit\">...\u003C\u002Fform>\n\u003C\u002Ftemplate>\n","vue",[33,387,388,412,447,461,466,475,479,489,513],{"__ignoreMap":174},[178,389,390,393,397,400,403,406,409],{"class":180,"line":181},[178,391,392],{"class":195},"\u003C",[178,394,396],{"class":395},"s9eBZ","script",[178,398,399],{"class":191}," setup",[178,401,402],{"class":191}," lang",[178,404,405],{"class":195},"=",[178,407,408],{"class":199},"\"ts\"",[178,410,411],{"class":195},">\n",[178,413,414,417,420,422,425,428,431,434,438,441,444],{"class":180,"line":188},[178,415,416],{"class":236},"  const",[178,418,419],{"class":240}," submit",[178,421,244],{"class":236},[178,423,424],{"class":191}," handleSubmit",[178,426,427],{"class":195},"(",[178,429,430],{"class":236},"async",[178,432,433],{"class":195}," (",[178,435,437],{"class":436},"s4XuR","values",[178,439,440],{"class":195},") ",[178,442,443],{"class":236},"=>",[178,445,446],{"class":195}," {\n",[178,448,449,452,455,458],{"class":180,"line":220},[178,450,451],{"class":236},"    await",[178,453,454],{"class":195}," api.",[178,456,457],{"class":191},"signup",[178,459,460],{"class":195},"(values)\n",[178,462,463],{"class":180,"line":227},[178,464,465],{"class":195},"  })\n",[178,467,468,471,473],{"class":180,"line":233},[178,469,470],{"class":195},"\u003C\u002F",[178,472,396],{"class":395},[178,474,411],{"class":195},[178,476,477],{"class":180,"line":256},[178,478,224],{"emptyLinePlaceholder":223},[178,480,482,484,487],{"class":180,"line":481},7,[178,483,392],{"class":195},[178,485,486],{"class":395},"template",[178,488,411],{"class":195},[178,490,492,495,498,501,503,506,509,511],{"class":180,"line":491},8,[178,493,494],{"class":195},"  \u003C",[178,496,497],{"class":395},"form",[178,499,500],{"class":191}," @submit.prevent",[178,502,405],{"class":195},[178,504,505],{"class":199},"\"submit\"",[178,507,508],{"class":195},">...\u003C\u002F",[178,510,497],{"class":395},[178,512,411],{"class":195},[178,514,516,518,520],{"class":180,"line":515},9,[178,517,470],{"class":195},[178,519,486],{"class":395},[178,521,411],{"class":195},[18,523,525],{"id":524},"v-register-on-my-component-does-nothing-typing-doesnt-update-the-form","\"v-register on my component does nothing (typing doesn't update the form)\"",[14,527,528,531,532,535,536,539,540,543,544,547,548,551,552,555],{},[33,529,530],{},"\u003CMyComponent v-register=\"...\">"," works only when the component's\nrendered root element is one Vue's directive can bind: ",[33,533,534],{},"\u003Cinput>",",\n",[33,537,538],{},"\u003Ctextarea>",", or ",[33,541,542],{},"\u003Cselect>",". For components whose root is a ",[33,545,546],{},"\u003Cdiv>","\n\u002F ",[33,549,550],{},"\u003Clabel>"," \u002F styled wrapper, the directive can't read ",[33,553,554],{},"el.value","\noff the wrapper and skips listener attachment to avoid the bubbled-\nwrite bug — typing into a descendant input goes nowhere.",[14,557,558,559,562],{},"The fix: call ",[33,560,561],{},"useRegister()"," in the child's setup and re-bind\nv-register onto an inner native element:",[169,564,566],{"className":383,"code":565,"language":385,"meta":174,"style":174},"\u003C!-- StyledInput.vue -->\n\u003Cscript setup lang=\"ts\">\n  import { useRegister } from 'attaform'\n  const register = useRegister()\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cdiv class=\"wrapper\">\n    \u003Cinput v-register=\"register\" \u002F>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n",[33,567,568,573,589,603,618,626,630,638,655,674,684],{"__ignoreMap":174},[178,569,570],{"class":180,"line":181},[178,571,572],{"class":184},"\u003C!-- StyledInput.vue -->\n",[178,574,575,577,579,581,583,585,587],{"class":180,"line":188},[178,576,392],{"class":195},[178,578,396],{"class":395},[178,580,399],{"class":191},[178,582,402],{"class":191},[178,584,405],{"class":195},[178,586,408],{"class":199},[178,588,411],{"class":195},[178,590,591,594,597,600],{"class":180,"line":220},[178,592,593],{"class":236},"  import",[178,595,596],{"class":195}," { useRegister } ",[178,598,599],{"class":236},"from",[178,601,602],{"class":199}," 'attaform'\n",[178,604,605,607,610,612,615],{"class":180,"line":227},[178,606,416],{"class":236},[178,608,609],{"class":240}," register",[178,611,244],{"class":236},[178,613,614],{"class":191}," useRegister",[178,616,617],{"class":195},"()\n",[178,619,620,622,624],{"class":180,"line":233},[178,621,470],{"class":195},[178,623,396],{"class":395},[178,625,411],{"class":195},[178,627,628],{"class":180,"line":256},[178,629,224],{"emptyLinePlaceholder":223},[178,631,632,634,636],{"class":180,"line":481},[178,633,392],{"class":195},[178,635,486],{"class":395},[178,637,411],{"class":195},[178,639,640,642,645,648,650,653],{"class":180,"line":491},[178,641,494],{"class":195},[178,643,644],{"class":395},"div",[178,646,647],{"class":191}," class",[178,649,405],{"class":195},[178,651,652],{"class":199},"\"wrapper\"",[178,654,411],{"class":195},[178,656,657,660,663,666,668,671],{"class":180,"line":515},[178,658,659],{"class":195},"    \u003C",[178,661,662],{"class":395},"input",[178,664,665],{"class":191}," v-register",[178,667,405],{"class":195},[178,669,670],{"class":199},"\"register\"",[178,672,673],{"class":195}," \u002F>\n",[178,675,677,680,682],{"class":180,"line":676},10,[178,678,679],{"class":195},"  \u003C\u002F",[178,681,644],{"class":395},[178,683,411],{"class":195},[178,685,687,689,691],{"class":180,"line":686},11,[178,688,470],{"class":195},[178,690,486],{"class":395},[178,692,411],{"class":195},[14,694,695,696,699,700,704,705,708],{},"The dev-mode console warning ",[33,697,698],{},"v-register on \u003Cdiv> is a no-op …","\npoints here. See the ",[102,701,703],{"href":702},"\u002Fdocs\u002Frecipes\u002Fpersistence-edge-cases#component-support","components recipe","\nfor the four supported patterns (native root, useRegister,\ninjectForm for compound components, and the ",[33,706,707],{},"assignKey","\nescape hatch).",[18,710,712],{"id":711},"submit-fails-with-no-value-supplied-on-a-field-the-user-can-leave-blank","\"Submit fails with 'No value supplied' on a field the user can leave blank\"",[14,714,715,716,719],{},"The path is in the form's ",[33,717,718],{},"blankPaths"," set and bound to a required\nschema. Three resolutions, depending on intent:",[291,721,722,739,753],{},[294,723,724,727,728,114,731,734,735,738],{},[28,725,726],{},"The field is genuinely optional."," Wrap the schema:\n",[33,729,730],{},"z.string().optional()",[33,732,733],{},"z.number().nullable()",", or\n",[33,736,737],{},"z.string().default('')",". Optional \u002F nullable \u002F has-default\nschemas accept the empty case and don't raise.",[294,740,741,748,749,752],{},[28,742,743,744,747],{},"The field is required but the consumer wants ",[33,745,746],{},"''"," to count as\n\"filled\"."," Supply an explicit default at construction:\n",[33,750,751],{},"defaultValues: { email: '' }",". The library reads this as \"empty\nstring is intentional\" and skips the auto-mark for that leaf.",[294,754,755,758,759,762,763,766,767,766,769,772],{},[28,756,757],{},"The library should treat a blank field as \"user didn't fill\nit.\""," Working as intended — the synthesized error\n(",[33,760,761],{},"code: 'atta:no-value-supplied'",") prevents silently submitting\n",[33,764,765],{},"0"," \u002F ",[33,768,746],{},[33,770,771],{},"false"," for an unfilled required field.",[14,774,775,776,780,781,784],{},"See ",[102,777,779],{"href":778},".\u002Frecipes\u002Fapp-defaults","app-defaults recipe"," for the\nauto-mark rules and the ",[33,782,783],{},"unset"," sentinel.",[18,786,788],{"id":787},"persisted-state-is-gone-after-a-schema-change","\"Persisted state is gone after a schema change\"",[14,790,791,792,795,796,799],{},"Working as intended. As of 0.12, storage keys carry the schema's\nfingerprint (",[33,793,794],{},"${base}:${fingerprint}","). When the schema changes\nshape, the fingerprint changes, the old key becomes unreachable,\nand the orphan-cleanup pass on the next mount removes it. No\nmanual ",[33,797,798],{},"version"," bump needed — it's automatic.",[14,801,802],{},"If the schema didn't change shape but state was wiped anyway, the\nfingerprint is over-sensitive. Common causes in custom adapters:",[291,804,805,813],{},[294,806,296,807,809,810,49],{},[33,808,299],{}," mixes function-valued metadata\n(refinement bodies, transform fns) into the hash without\ncollapsing to a sentinel. Two refines of the same shape produce\ndifferent hashes; consumers see drafts vanish on every refine\nedit. Collapse functions to ",[33,811,812],{},"'fn:*'",[294,814,815],{},"The fingerprint includes a timestamp or per-call random ID. It\nmust be a pure function of the schema's structure.",[14,817,818,819,822],{},"If you genuinely need to invalidate drafts without changing the\nschema (e.g. shipping a security fix that requires fresh state),\ncall ",[33,820,821],{},"form.clearPersistedDraft()"," on mount or evict the registry\nentry programmatically.",[18,824,826,827,830],{"id":825},"i-see-prevfirst-getting-flagged-as-redundant","\"I see ",[33,828,829],{},"prev?.first ?? ''"," getting flagged as redundant\"",[14,832,833,834,837,838,841,842,845,846,849],{},"Working as intended. As of 0.12, the path-form ",[33,835,836],{},"setValue"," callback\nreceives a fully-defaulted ",[33,839,840],{},"prev"," — the runtime calls\n",[33,843,844],{},"getDefaultAtPath"," on missing slots before invoking the callback,\nso consumer code can read ",[33,847,848],{},"prev.first.toUpperCase()"," directly. Drop\nthe optional chain.",[14,851,852,853,855,856,859,860,863,864,867,868,871,872,875,876,114,879,882],{},"Whole-form callback ",[33,854,840],{}," is ",[33,857,858],{},"WriteShape\u003CForm>",". Array reads\n(",[33,861,862],{},"prev.posts[5]",") carry ",[33,865,866],{},"| undefined"," from your tsconfig's\n",[33,869,870],{},"noUncheckedIndexedAccess: true"," — narrow with ",[33,873,874],{},"?."," or a guard.\nIteration (",[33,877,878],{},"for (const p of prev.posts)",[33,880,881],{},"prev.posts.map(...)",")\nkeeps the strict element type; that's the flag's intended scope.",[18,884,320,886,889],{"id":885},"formvaluesposts0titletouppercase-started-type-erroring",[33,887,888],{},"form.values.posts[0].title.toUpperCase()"," started type-erroring\"",[14,891,892,893,895],{},"Working as intended. Once a read path crosses an array index, the\nresult carries ",[33,894,866],{}," — the runtime can return undefined for\nout-of-bounds reads, so the type tracks that. Narrow with optional\nchaining:",[169,897,899],{"className":171,"code":898,"language":173,"meta":174,"style":174},"form.values.posts[0]?.title?.toUpperCase() ?? ''\n",[33,900,901],{"__ignoreMap":174},[178,902,903,906,908,911,914,917,920],{"class":180,"line":181},[178,904,905],{"class":195},"form.values.posts[",[178,907,765],{"class":240},[178,909,910],{"class":195},"]?.title?.",[178,912,913],{"class":191},"toUpperCase",[178,915,916],{"class":195},"() ",[178,918,919],{"class":236},"??",[178,921,922],{"class":199}," ''\n",[14,924,925,926,929,930,114,933,114,936,939,940,942],{},"Or read from ",[33,927,928],{},"form.fields.posts[0].title.value"," if you also want\nthe per-field flags (",[33,931,932],{},"dirty",[33,934,935],{},"errors",[33,937,938],{},"touched",") alongside the\nvalue. The same ",[33,941,866],{}," taint applies; narrow the same way.",[14,944,945],{},"Tuple positions stay strict — out-of-bounds is a type-system error\non tuples, not a runtime case.",[18,947,949,950,953],{"id":948},"ts-was-happy-but-formvaluescontacts42name-crashed-at-runtime","\"TS was happy but ",[33,951,952],{},"form.values.contacts[42].name"," crashed at runtime\"",[14,955,956,957,959,960,963,964,967,968,49],{},"Try enabling ",[33,958,870],{}," in your tsconfig — it\nmakes ",[33,961,962],{},"arr[N]"," reads return ",[33,965,966],{},"T | undefined"," so the type system\ncatches stale indices. See\n",[102,969,973],{"href":970,"rel":971},"https:\u002F\u002Fgithub.com\u002Fattaform\u002Fattaform\u002Fblob\u002Fmain\u002FREADME.md#recommended-tsconfig",[972],"nofollow","README → Recommended tsconfig",[18,975,977],{"id":976},"focus-jumped-to-a-field-i-didnt-expect-on-submit","\"Focus jumped to a field I didn't expect on submit\"",[14,979,980,983,984,987,988,991,992,995],{},[33,981,982],{},"focusFirstError"," (and the ",[33,985,986],{},"onInvalidSubmit: 'focus-first-error'","\npolicy) targets the ",[28,989,990],{},"visually-first"," errored field — DOM-tree\norder via ",[33,993,994],{},"compareDocumentPosition",". If your template renders\nfields in a different order than the schema declares them, the\nfield rendered above another wins regardless of declaration order.",[14,997,998,999,1002,1003,1006,1007,1010,1011,1014,1015,1017],{},"Caveat: CSS ",[33,1000,1001],{},"order:"," flexbox\u002Fgrid reordering is NOT respected.\nA child with ",[33,1004,1005],{},"order: -1"," appears visually first but stays in its\nDOM-tree position, and the focus algorithm uses DOM-tree position.\nThe tradeoff is intentional — visual-order via\n",[33,1008,1009],{},"getBoundingClientRect"," would force sync layout per comparison and\nbreak under ",[33,1012,1013],{},"display: none",". If you genuinely need CSS-",[33,1016,1001],{},"\nawareness, file an issue with a concrete repro.",[14,1019,1020,1021,1024,1025,1028,1029,1032],{},"Scope is per ",[33,1022,1023],{},"useForm()"," callsite: two ",[33,1026,1027],{},"useForm({ key })"," calls\nsharing a key (sidebar + main) each focus only their own\nregistered elements. Children reaching the form via ",[33,1030,1031],{},"injectForm()","\ninherit their ancestor's instance ID, so parent-submit still\nfocuses inputs registered by deep children.",[18,1034,1036],{"id":1035},"undo-brought-back-stale-field-errors","\"Undo brought back stale field errors\"",[14,1038,1039,1040,1043,1044,49],{},"By design. An undo snapshot captures the form value AND the errors\nthat were live at the time. If you want an undo to land on a\nclean error state, call ",[33,1041,1042],{},"form.clearFieldErrors()"," right after\n",[33,1045,1046],{},"undo()",[18,1048,1050],{"id":1049},"my-custom-adapters-errors-have-the-wrong-path","\"My custom adapter's errors have the wrong path\"",[14,1052,1053,1056,1057,1060,1061,1064],{},[33,1054,1055],{},"validateAtPath"," returns ",[33,1058,1059],{},"ValidationError[]"," with ",[33,1062,1063],{},"path: (string | number)[]",". Whatever your adapter emits is what downstream code\nuses. Mismatches between your adapter's path format and the rest\nof the app's usually stem from:",[291,1066,1067,1079],{},[294,1068,1069,1070,1072,1073,1075,1076,1078],{},"Mixing string \u002F number types for array indices. Emit ",[33,1071,73],{}," (number ",[33,1074,765],{},"), not ",[33,1077,77],{}," (string).",[294,1080,1081],{},"Paths relative to a sub-schema leaking through when the caller\nasked for an absolute path — re-stamp error paths with the\nfield prefix before returning.",[18,1083,1085,1086,1088],{"id":1084},"my-custom-adapter-is-missing-code-on-its-validationerrors","\"My custom adapter is missing ",[33,1087,33],{}," on its ValidationErrors\"",[14,1090,1091,1092,1095,1096,1099,1100,1103],{},"Every ",[33,1093,1094],{},"ValidationError"," carries a required ",[33,1097,1098],{},"code: string",". Pick a\nstable scope prefix for your adapter (e.g. ",[33,1101,1102],{},"'mylib:'",") and forward\nthe underlying issue's code under it:",[169,1105,1107],{"className":171,"code":1106,"language":173,"meta":174,"style":174},"return {\n  errors: result.issues.map((issue) => ({\n    path: issue.path,\n    message: issue.message,\n    formKey: '',\n    code: `mylib:${issue.code ?? 'unknown'}`,\n  })),\n  \u002F\u002F ...\n}\n",[33,1108,1109,1116,1137,1142,1147,1156,1178,1183,1188],{"__ignoreMap":174},[178,1110,1111,1114],{"class":180,"line":181},[178,1112,1113],{"class":236},"return",[178,1115,446],{"class":195},[178,1117,1118,1121,1124,1127,1130,1132,1134],{"class":180,"line":188},[178,1119,1120],{"class":195},"  errors: result.issues.",[178,1122,1123],{"class":191},"map",[178,1125,1126],{"class":195},"((",[178,1128,1129],{"class":436},"issue",[178,1131,440],{"class":195},[178,1133,443],{"class":236},[178,1135,1136],{"class":195}," ({\n",[178,1138,1139],{"class":180,"line":220},[178,1140,1141],{"class":195},"    path: issue.path,\n",[178,1143,1144],{"class":180,"line":227},[178,1145,1146],{"class":195},"    message: issue.message,\n",[178,1148,1149,1152,1154],{"class":180,"line":233},[178,1150,1151],{"class":195},"    formKey: ",[178,1153,746],{"class":199},[178,1155,535],{"class":195},[178,1157,1158,1161,1164,1166,1168,1170,1173,1176],{"class":180,"line":256},[178,1159,1160],{"class":195},"    code: ",[178,1162,1163],{"class":199},"`mylib:${",[178,1165,1129],{"class":195},[178,1167,49],{"class":199},[178,1169,33],{"class":195},[178,1171,1172],{"class":236}," ??",[178,1174,1175],{"class":199}," 'unknown'}`",[178,1177,535],{"class":195},[178,1179,1180],{"class":180,"line":481},[178,1181,1182],{"class":195},"  })),\n",[178,1184,1185],{"class":180,"line":491},[178,1186,1187],{"class":184},"  \u002F\u002F ...\n",[178,1189,1190],{"class":180,"line":515},[178,1191,1192],{"class":195},"}\n",[14,1194,1195,1196,1200,1201,1204,1205,1208],{},"See the ",[102,1197,1199],{"href":1198},".\u002Frecipes\u002Fcustom-adapter","custom-adapter recipe"," for\nthe full contract including ",[33,1202,1203],{},"isRequiredAtPath"," (used by the blank\nvalidation augmentation) and ",[33,1206,1207],{},"getSlimPrimitiveTypesAtPath"," (used\nby the slim-primitive write gate).",[18,1210,1212],{"id":1211},"dev-warnings-dont-fire-am-i-in-production","\"Dev warnings don't fire — am I in production?\"",[14,1214,1215,1216,1219,1220,1223,1224,1227,1228,1231],{},"The library uses a ",[33,1217,1218],{},"__DEV__"," flag that resolves from\n",[33,1221,1222],{},"process.env.NODE_ENV !== 'production'"," at module load. Standard\nbundlers (Vite, Webpack, Rollup with ",[33,1225,1226],{},"@rollup\u002Fplugin-replace",")\ninline ",[33,1229,1230],{},"process.env.NODE_ENV"," at build time so the flag becomes\na constant the compiler can dead-code-eliminate.",[14,1233,1234,66,1237,1240,1241,1243,1244,1246],{},[28,1235,1236],{},"If you're importing the library directly from a browser-native\nESM CDN (esm.sh, Skypack, unpkg) without a bundler,",[33,1238,1239],{},"process","\nis undefined and ",[33,1242,1218],{}," is permanently ",[33,1245,771],{}," — every dev-mode\nwarning is silenced even though you're clearly in development.\nThe library works correctly; only the diagnostic surface degrades.",[14,1248,1249,1250,1252],{},"The fix is to put a bundler in your pipeline (or use a CDN that\nserves a bundled distribution). For production apps, this is\nalready the case; for prototype-style CDN imports, it's a\ndeliberate trade-off: no ",[33,1251,1230],{}," replacement, no\ndev warnings.",[18,1254,1256],{"id":1255},"still-stuck","Still stuck?",[14,1258,1259,1260,1263,1264,1267],{},"Reproduce in ",[33,1261,1262],{},"test\u002F"," — vitest is configured, jsdom is set up for\ndirective work, and the Nuxt fixture is one command away (",[33,1265,1266],{},"pnpm test -- test\u002Fssr.test.ts","). If your repro passes, the bug is\nlikely in your app wiring; if it fails, it's probably worth a PR.",[1269,1270,1271],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}",{"title":174,"searchDepth":188,"depth":188,"links":1273},[1274,1275,1276,1277,1278,1280,1282,1283,1284,1285,1287,1289,1291,1292,1293,1294,1296,1297],{"id":20,"depth":188,"text":21},{"id":85,"depth":188,"text":86},{"id":159,"depth":188,"text":160},{"id":285,"depth":188,"text":286},{"id":319,"depth":188,"text":1279},"\"register('email') returns a never-typed value\"",{"id":365,"depth":188,"text":1281},"\"handleSubmit doesn't run when I submit the form\"",{"id":524,"depth":188,"text":525},{"id":711,"depth":188,"text":712},{"id":787,"depth":188,"text":788},{"id":825,"depth":188,"text":1286},"\"I see prev?.first ?? '' getting flagged as redundant\"",{"id":885,"depth":188,"text":1288},"\"form.values.posts[0].title.toUpperCase() started type-erroring\"",{"id":948,"depth":188,"text":1290},"\"TS was happy but form.values.contacts[42].name crashed at runtime\"",{"id":976,"depth":188,"text":977},{"id":1035,"depth":188,"text":1036},{"id":1049,"depth":188,"text":1050},{"id":1084,"depth":188,"text":1295},"\"My custom adapter is missing code on its ValidationErrors\"",{"id":1211,"depth":188,"text":1212},{"id":1255,"depth":188,"text":1256},"md",{},"\u002Fdocs\u002Ftroubleshooting",{"title":5,"description":16},"docs\u002Ftroubleshooting","E9p5zbs1eMv6dRZ25Gy6AQKB6WeBB47zT0P7EEdL7AY",1777934135560]