When it says no
star-burxt refuses things. Each refusal is here with what to write instead.
Nothing on this page is a bug. A refusal means the problem reached you in a terminal instead of reaching a user on a screen.
“unknown variable: nmae”
A slot or a handler names something that is not there.
Hello {{ nmae }}
Fix: check the spelling against your :props: line. If the value is new, add it there.
“cannot apply + to Int and String”
You mixed a number and text.
:button: on:click=count + "one"
increment
:!button:
Fix: count + 1. If you want text, convert first: to_string(count) + "one".
“this multiplication … means rounding it”
You multiplied money and did not say how to round.
:button: on:click=total * 1.5
apply surcharge
:!button:
Fix: say how — :props: total: Decimal<2, RoundHalfEven> — or keep the exact answer with
Decimal<4>. Chapter 5 is about this one.
“mystery is not a block this host knows”
You used a block name that is not an element.
:mystery:
:!mystery:
Fix: use one of these, or check the spelling.
div span p section article header footer nav form label
strong em h1–h6 ul ol li input img br hr button
Plus props, for and if, which are not elements.
“this document declares no props block”
A component has to say what it is given, and the props block is that declaration. Without one there
is nothing to render from:
# A component with nothing declared
:p: child={to_string(count)}
:!p:
Fix: put a props block first, naming what comes in:
:props: count: Int
:!props:
# Today
:p: child={to_string(count)}
:!p:
“class={…} is a single-brace value”
Single braces are for child=. In any other attribute, write the interpolation you use everywhere
else:
:span: class={{ mark(task.done) }} child={task.label}
:!span:
Why it is refused rather than allowed. class={mark(x)} reaches the compiler as the text
"{mark(x)}", and it happens to produce the right class because Burxt interpolates braces inside its
own string literals. It works by accident — and a value holding a literal brace would put
{mark(x)} straight into the page with nothing to say so.
“on:hover is not an event this host can wire”
There is no hover event. Hovering is CSS, not something that happens once. So this is refused:
:button: on:hover=Msg.Peek
peek
:!button:
and this is the answer:
===style.local
.card:hover { border-color: #333; }
===
If a hover has to change your state rather than its appearance, the events are mouseenter and
mouseleave.
Two others get the same treatment, because they are the ones people reach for:
| you wrote | the message says |
|---|---|
on:keypress |
use on:keydown — keypress is deprecated and misses keys |
on:mousemove |
use on:pointermove — it covers a mouse, a pen and a finger |
For anything else the message lists what is wired, which is most DOM events — see Events.
star refuses an event it cannot deliver rather than accepting it and doing nothing. A handler that never runs is the worst failure a page can have: nothing breaks, nothing is logged, and you stare at the screen wondering what you got wrong.
“input is a void element, so it cannot have a body”
Some elements hold nothing.
:input: on:input=name
type here
:!input:
Fix: leave the body empty. Put the text in a label beside it. This applies to input, img,
br and hr.
“button takes phrasing content, so it cannot contain a heading”
You put a block-level thing inside a text-level element.
:button: on:click=go
# Click me
:!button:
Fix: use text. button, label, span, strong, em and the headings hold text; everything
else holds anything.
This is HTML’s rule — a heading inside a button is invalid markup and browsers handle it unpredictably.
“key belongs on a for, not on an if”
:if: ready key thing.id
:p:
Everything is set.
:!p:
:!if:
Fix: drop the key. A key tells rows apart, and an if has one branch with nothing to tell
apart.
“an on: handler inside a for is not supported yet”
:for: line in lines key line.id
:button: on:click=line.id
remove
:!button:
:!for:
This one is a limit rather than a mistake, and it is the only refusal on this page that will eventually go away.
A handler runs later, on its own, with the component’s state. By then line no longer exists — it
was only there while the page was being drawn. The framework needs to remember which row rather
than which value, which is designed and not built.
Fix, today: drive the change from the whole list rather than from one row. A button outside the loop works.