Patch Changes
-
#3262
c467f09Thanks @DylanPiercey! - Error in development when a<for>tag'sbyattribute returns an invalid key — a non-string/number value (e.g. an object, which collapses every item to[object Object]) or a duplicate value. These previously only logged aconsole.errorwarning while silently corrupting keyed reconciliation (state, focus, and animations attaching to the wrong items). The checks areMARKO_DEBUG-only and stripped from production. -
#3253
ce92da6Thanks @DylanPiercey! - Fix<for to>/<for until>range loops corrupting their DOM on the first update after an SSR resume. Without an explicitby, these loops are keyed by their iteration value, but the HTML writer decided whether to serialize the loop key by comparing the key against the iteration value rather than the positional index — so the key was never written. On resume the branches were keyed by position while the client re-keyed them by value, and any range loop where the value differs from the position (fromother than0, or astepother than1) with resumable content (event handlers,<let>, etc.) would tear down and rebuild its branches. The writer now compares against the positional index, matching<for of>. -
#3251
8fb0bd7Thanks @DylanPiercey! - Error on native tags when an attribute name is a recognizable idiom from another framework (React, Svelte, Vue) that is not valid in Marko, with a suggestion for the correct syntax. These previously compiled but silently produced a junk attribute (HTML attribute names are case-insensitive, so e.g.classNamebecomes theclassnameattribute, notclass). Examples:- React:
className→class,htmlFor→for,defaultValue→value,defaultChecked→checked,acceptCharset→accept-charset,httpEquiv→http-equiv - Svelte:
class:active→class={ active: condition },style:color→style={ color: value },on:click→onClick,bind:value→value:=state - Vue:
v-if→<if>,v-for→<for>,v-model→value:=state,v-on:click→onClick,v-bind:class→class
The check runs for both static attributes (compile error) and dynamic/spread attributes (
MARKO_DEBUG-only runtime error in the server and client attribute runtimes). Only native tags are checked — custom components may still accept input props with these names. (Vue's:/@and Angular's[/(/*shorthands already error as invalid attribute names.) - React:
-
#3264
d3055efThanks @DylanPiercey! - Fix<lifecycle>onDestroynot running after resume when it is the only interactive feature of a component nested in control flow. The lifecycle cleanup is registered through$signalat runtime, which requires the scope to resume with its closest branch linked; the section is now marked so that link is serialized. -
#3260
262f277Thanks @DylanPiercey! - Error in development when a native tag attribute or text interpolation receives a value that can't meaningfully render (a plain object, a promise, a symbol, or a function). For example<div title={ ... }>or${somePromise}previously rendered useless output like[object Object]. Object and function attribute literals are also caught at compile time.class/style,content, event handlers, and change handlers, as well as arrays and values with a meaningfultoString, are unaffected. -
#3261
e9f04e3Thanks @DylanPiercey! - Warn in development when a controlled<select>'svaluematches no<option>. A single select always forces one option selected, so an unmatched value cannot round-trip through SSR resume (the server serializes which option is selected, not the value) and the controlled value is lost on the client. Both the server and client runtimes now emit aMARKO_DEBUGconsole.errorso the mistake is surfaced during development. -
#3259
cbf7a49Thanks @DylanPiercey! - Fix the SSR serializer emitting an own__proto__data property as a prototype setter. A plain object with an own__proto__key (e.g. produced byJSON.parse) was serialized as{__proto__: value}, which on deserialization sets the object's prototype instead of creating an own property — dropping the data and mutating the prototype. Such keys are now emitted as a computed key ({["__proto__"]: value}) so they round-trip as normal own properties. -
#3252
e8c75dbThanks @DylanPiercey! - Fix a controlled form binding (value/checked/checkedValue/opentogether with its*Changehandler) applied through a spread (<input ...attrs>) continuing to take effect after the spread drops it. The controlled handler and type were only written by the controllable setters and never cleared, so the persistent input listener kept firing the stale change handler and mutating state on an element that was no longer controlled. The binding is now reset each render and re-established only when the controlling attribute is still present. -
#3254
e8b06b5Thanks @DylanPiercey! - Fix text-only native tags (<title>,<style>,<html-comment>, etc.) corrupting dynamic text in the client build. When such a tag's body contained a placeholder, the compiler built the template literal'srawstring escaping only backticks — not backslashes or${. Babel emits code fromraw, so a backslash in the static text became a JS escape sequence at runtime (e.g.\b→ backspace) and a literal${became a stray interpolation; the server (HTML) build used the correct escaper, so SSR and the hydrated client diverged. The compiler now reuses the sharedescapeTemplateRawhelper for these literals.