Compile errors
situ fails closed: everything outside the compiled dialect, the seam, or the composition envelope is a CompileError raised at compile time (in dev, surfaced on your framework's debug page — Litestar's or Flask's; in the lint loop via tests and situ check), so problems surface as visible errors while you develop. The compiler carries 111 distinct rejection sites; the inline messages are maintained as part of the API. This page catalogs the ones you'll actually meet, with their fixes.
The seam
| Message (abridged) |
Fix |
server-sited 'x' cannot be read on the client; DB-backed state stays on the server |
Render it server-side (Jinja / context()), ship named row fields explicitly, or push a value with signal() from a command |
cannot assign server-sited signal 'x' on the client |
Mutate through a command (await facade...) |
cannot assign url-sited signal 'x' on the client |
Url state is set by navigation — use a link |
refusing to compile a loop over server-sited 'x': DB iteration stays on the server |
Loop in context() or the facade; the template's Jinja {% for %} renders the result |
await in a client position (an @event, a client body) |
Only a handler body may await — which makes it a server command |
The dialect
| Message (abridged) |
Fix |
cannot compile expression: <NodeType> / statement not in the compiled dialect: <NodeType> |
Restructure into the dialect, or move the logic server-side |
| unknown name / unsupported call / unsupported method |
Only signals, row vars, and the whitelisted functions exist client-side |
f-string conversion (!r) or format spec (:.2f) rejected |
Format server-side, or simplify |
| membership can't chain with comparisons |
Split the condition |
| dict keys must be string constants |
|
Templates
| Message (abridged) |
Fix |
:each needs 'var in iterable' |
The binder value is row in signal |
a binder/event on the :each element itself |
Put :each on a wrapper element |
a row event other than @click/@submit |
Restructure; rows support click/submit |
:bind on a non-Local signal |
Two-way binding is client state by definition |
reactive element outside <header> / data-region (silently inert at runtime) |
Respect the two runtime rules |
Composition
| Message (abridged) |
Fix |
unknown component <Tag> |
Register it (components= / Context.from_dir) — and run situ check in your lint loop so this fails fast |
| missing / extra / duplicate / unused Prop or Emit binding |
Match the child's declared contract exactly |
Inject with no ancestor Provide |
Provide it on an ancestor, or thread a Prop |
content given to a child that declares no <slot> |
Add a <slot> to the child (content would otherwise vanish) |
| signal declared by two components / minted-name collision |
Rename — flat-island names are per-tree |
per-instance state inside a :each via an intermediate |
Fenced: give the state to the row (top-level :each) or lift it |
bare prop on a nested host — use the colon form :prop= |
Only :/@ bindings substitute through composition levels |
component placement cycle: A > B > A / self-placement |
Composition is a finite tree; data-driven recursion uses :each + :tree |
a top-level component's <style> |
Only child components are CSS-scoped; move page styles to the page |
declui
| Message (abridged) |
Fix |
| unmapped field type |
Add a widget= or change the type — declui never degrades to a text box |
| predicate: identifier / call / node outside the grammar |
Stay in the predicate vocabulary |
| Decimal relational compare in a predicate |
String-valued for precision; compare equality, or model as int/float |
@action gate referencing a date field, or calling a function |
The server-row grammar excludes them |
model field named value / editing; action named reset |
Reserved names |
| a local variable shadowing a field in a sync action |
Rename the local — it would silently write the signal |
server mount passed screens= / rows= / choices=; service_type without context |
The fail-closed mount rules |
The philosophy
A bounded compiler earns its keep by where it stops. If an error message doesn't point at the fix, treat that as a bug and report the message text.