docs: add mistake #19 — optional TypeScript params break vite build SSR

Documents the param?: Type pattern that esbuild mishandles in .svelte
files (strips the type but leaves ?, producing invalid JavaScript). Adds
the full write-up to REFERENCE__Common_Agent_Mistakes.md and a summary
entry #10 to BOOTSTRAP__AI_Agent_Quickstart.md §7.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-06-22 19:04:52 -04:00
parent 3bc93857dd
commit 6c822bc466
2 changed files with 49 additions and 0 deletions

View File

@@ -308,6 +308,9 @@ Read this section first, then open the reference doc when your task touches one
field, SWR-await-after-write races, and stateful/conditional sync gates that desync local field, SWR-await-after-write races, and stateful/conditional sync gates that desync local
state from history rather than current config. See the Pres Mgmt Config sync overhaul state from history rather than current config. See the Pres Mgmt Config sync overhaul
(2026-06-16) in `PROJECT__AE_Events_PressMgmt_Config_Cleanup.md` for the full incident. (2026-06-16) in `PROJECT__AE_Events_PressMgmt_Config_Cleanup.md` for the full incident.
10. **`param?: Type` in `.svelte` function/snippet parameters** — breaks `vite build` (SSR step)
silently: dev server is fine, Docker/production builds fail with "Expected ',', got '?'".
Use `param: Type | undefined = undefined` instead. See mistake #19 in the reference doc.
The reference doc also includes a short archive list for older, less-relevant historical incidents. The reference doc also includes a short archive list for older, less-relevant historical incidents.

View File

@@ -248,6 +248,52 @@ function-level gate.
the gate (sync unconditionally) loses any real behavior — query production data for whether the gate (sync unconditionally) loses any real behavior — query production data for whether
the gate is ever actually in the "off" state before assuming it needs to exist. the gate is ever actually in the "off" state before assuming it needs to exist.
### 19) `param?: Type` in `.svelte` function or snippet parameter positions
**Impact:** `vite build` SSR step fails with "Expected ',', got '?'" — Docker builds and
production deploys break. Dev server is unaffected (different code path), so the error is
invisible in local development and only surfaces in CI/CD or the first clean Docker build.
**What happened:** Source files used TypeScript optional-parameter syntax (`param?: Type`)
inside `.svelte` `<script lang="ts">` functions and `{#snippet}` parameter lists. esbuild
(Vite's dep pre-bundler/SSR transform) strips `: Type` from the type annotation but leaves
the `?` marker, producing `param?` — which is invalid JavaScript. Rollup then fails to parse
the compiled output, showing the original `.svelte` line number via source maps.
Five occurrences were found and fixed in 2026-06 across:
`reports_file_downloads.svelte`, `ae_comp__journal_entry_obj_id_view.svelte`,
`ae_comp__modal_journal_entry_config.svelte`, `launcher_file_cont.svelte`,
`ae_comp__badge_print_controls.svelte` (Svelte 5 `{#snippet}` param).
**Rule:** Never write `param?: Type` in function or snippet parameter positions inside
`.svelte` files. Use `param: Type | undefined = undefined` instead — this preserves the
same runtime behavior (calling without the argument passes `undefined`) and produces valid
JavaScript after TypeScript stripping.
```ts
// ❌ Breaks vite build (SSR environment):
function clean_part(s: any, max?: number): string { ... }
{#snippet field_actions(on_save: () => void, on_revert?: () => void)}
// ✅ Correct:
function clean_part(s: any, max: number | undefined = undefined): string { ... }
{#snippet field_actions(on_save: () => void, on_revert: (() => void) | undefined = undefined)}
```
This restriction applies **only inside `.svelte` files** — TypeScript `.ts` files are
processed by the TypeScript compiler directly and handle `?: Type` correctly. Interface and
type alias blocks inside `<script lang="ts">` are also fine (the Svelte compiler handles
those natively); the restriction is only for runtime function/snippet parameter lists.
Note: `scripts/postinstall.mjs` applies the same fix to flowbite-svelte's published dist
files, which ship with TypeScript optional params in function signatures. That script needs
to be maintained whenever flowbite-svelte is updated — check with:
`grep -rn "?:" node_modules/flowbite-svelte/dist/ | grep "function\|=>"`.
**Verify:** After writing any new function or `{#snippet}` in a `.svelte` file, scan for
`\w\?:` in the parameter list. Run `npm run build:dev` locally before any Docker build or
deploy — it will catch this within seconds.
--- ---
## Archived Historical Items (Pruned) ## Archived Historical Items (Pruned)