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
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.
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.

View File

@@ -248,6 +248,52 @@ function-level gate.
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.
### 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)