Skip to content

Diagnostics reference

Every diagnostic Lute prints carries a code. E- codes are errors: the document fails the check and lute check exits 1. W- codes are warnings: the document passes, unless --deny <CODE> or --deny-warnings promotes them. An E- code is never printed as a warning: whole-project check --wip reports the dead guards it spares as W-WIP, and the message names the error code the same guard has without the flag. lute --explain <CODE> prints a code’s entry below in the terminal, and an editor links each code to its section here.

A message says what is wrong in plain words. The spec sections behind a code are listed under it, each linked to its proposal, and --json output carries them in each diagnostic’s spec field.

A position file:line:column counts lines and columns from 1, and the column counts characters, not bytes: a Korean syllable or an emoji before the error is one column. --json span.column and lute scenario … reach causes[].column are the same number. The language server reports UTF-16 positions, as LSP requires.

An ::accept directive names no quest, gives quest a value that is not a quoted quest id, gives at a value other than "nextRun", or targets a quest declared accept="external" that already activates with its parent (making the acceptance a no-op). Whole-project check also judges each quest an ::accept or a reward kind’s effects.accepts names: it must be declared in the project (did-you-mean) and accept-driven — not a quest with start, nor a subquest child that activates with its parent; a reward’s is reported at its target= (or kind=) and names the reward.

Spec: dsl 0.21.0 §7a.3, dsl 0.24.0 §2, dsl 0.25.0 §5, dsl 0.50.0 §5.2

A repeatable beat answers the clock raise that presents it and advances into the next position, creating a repeating nested advances: cascade.

Spec: dsl 0.31.0 §1

An age-gated <match subject="app.rating"> covers neither a teen arm nor an <otherwise>, so a release build could hit no matching case.

Spec: dsl §11.2

A ::set directive writes to the app.* namespace, which content may never write because the engine or settings layer owns it exclusively.

Spec: dsl §9.5

A gated content line, <match> arm, <choice when>, or ::jump{when} carries a when guard that is provably always false, so it can never be shown or taken.

Spec: dsl 0.4.0 §5.2, dsl 0.4.0 §7.2, dsl 0.20.0 §5

A choice uses the removed as attribute; into names the run fact a choice records.

Spec: dsl 0.10.0 §4

An asset id string has the wrong number of /- or .-separated segments for its declared kind, or a fixed (const) segment does not match the value the kind requires.

Spec: dsl §7.2

A segment of an asset id is not a member of its declared enum, is not a number where one is required, or is not a known id in its provider’s catalog.

Spec: dsl §7.2

A pure-query asset kind’s id string is not a known id in its declared provider’s catalog.

Spec: dsl §7.2

A directive (plain ::directive or ::use) carries the timeline-position attribute at outside a <track> clip, where at is not valid.

Spec: dsl §7.5

A @def used as a directive attribute value, or as a ::use argument landing in a component-body attribute, does not fold to a compile-time constant because it depends on state.

Spec: dsl §5.1

An attribute value is delimited with a single quote or a curly (word-processor) quote instead of the required straight double quote ".

Spec: dsl §4.4, dsl §4.5

An attribute’s value does not match its declared type — for example a non-numeric duration/zoom/shake, a non-boolean flag, a bare identifier where a quoted string is required, or a value naming no member of its provider, domain, or entity kind. A text attribute (or the code beside one) is a quoted string: an @ref value is refused, since a @def has no translation of its own.

Spec: dsl 0.51.0 §5.2

An authoring attribute, tag attribute or frontmatter key is not lowerCamelCase (it contains _); the message names its lowerCamelCase spelling.

Spec: dsl 0.37.0 §2.1

A value is not a member of the closed enum, domain, or entity kind it must belong to — for example a content line’s emotion= outside the speaker’s declared emotions:, or an entity id outside its kind.

Spec: dsl 0.24.0 §4

A beat’s on, target, priority, or once attribute is malformed — an on that is not a name, a target on an occasion not declared target: true, a non-integer priority, a once outside run/user/false, a beat key with no on, a when reading the scene’s own not-yet-existing scene.* state, or a spentBy beside once: false or a share key.

Spec: dsl 0.21.0 §3, dsl 0.21.0 §5, dsl 0.28.0 §6

Two declarations of one lore document share an id: a bundle <beat> id repeated, or an <entry> whose id is a <beat>’s — the beat’s canonical id <document id>.<id> is also the entry’s alias, so visited() or a play’s expect.winner would name both.

Spec: dsl 0.28.0 §7

A scene beat’s when guard is provably always false, so the beat can never be selected.

Spec: dsl 0.21.0 §5

A player binding names an unknown effect or supplies a parameter that the named effect does not accept.

Spec: dsl 0.40.0 §5, dsl 0.40.0 §7.4

A player binding references a file that does not exist relative to assetsBase (a ui reference uses an assets: key first).

Spec: dsl 0.40.0 §5, dsl 0.46.0 §3.1

A player binding key is not a declared domain member, cast id, occasion, target, compiled staging value, or closed-domain ending screen member.

Spec: dsl 0.40.0 §5, dsl 0.46.0 §3.2

The player bindings YAML is malformed or contains an unknown key, or a written ui.title binds none of text, background, music or has an empty text.

Spec: dsl 0.40.0 §5, dsl 0.46.0 §3.2, dsl 0.47.0 §4.1

A player bindings section is newer than the file’s declared bindingsVersion line (vfx effect: custom 0.41, volumes 0.42, ui.ended 0.46, ui.title.text 0.47); raise bindingsVersion to the line the section needs.

Spec: dsl 0.47.0 §4.2

A non-empty <branch> has every <choice> guarded by a when, so every guard could be false at once and present an empty menu; at least one unguarded choice is required.

Spec: dsl §11.1

A timed <branch> has no valid always-eligible direct option named by default=.

Spec: dsl 0.40.0 §2.1

A <branch> or <hub> contains no <choice> at all, which would flatten to an unroutable choice.

Spec: dsl §7.3

A <branch prompt> or <hub prompt> value is missing or an empty string, but the prompt must be the non-empty sentence the UI shows; its {{…}} markers are rendered like a choice label’s.

Spec: dsl 0.11.1 §4, dsl 0.23.0 §4, dsl 0.52.0 §6.1

A <branch timeout> value does not parse as a positive whole number of seconds.

Spec: dsl 0.11.1 §4

A plugin directive declares layer: bridge and bridgeCall semantics, but no effects.writes entry reads a bridge result (fromBridgeResult), so the call would compile as a record nothing waits for; add a fromBridgeResult write or remove layer: bridge.

Spec: dsl 0.41.1 §3.5

A ::camera directive names none of focus, framing, move or transition, so it has nothing to do.

Spec: dsl 0.37.0 §3.3

A ::camera directive uses a removed numeric or legacy attribute (zoom, moveX, moveY, shake, reset, easing); camera values are now project-declared framing, cameraMove or transition members, so the attribute must be migrated by hand.

Spec: dsl 0.37.0 §3.3, dsl 0.37.0 §4

Two documents in the same project resolve different capability snapshots, so the project has no single capabilityVersion to index.

Spec: dsl §13

A content line’s speaker, or a ::actor{character}/::camera{focus} literal, names an id outside the project’s declared cast.

Spec: dsl 0.23.0 §7, dsl 0.24.0 §4

A CEL expression in a condition slot, def body, or present:/beat when does not parse as valid CEL syntax.

Spec: dsl 0.4.0 §8.1

A CEL expression uses a construct outside the restricted Lute-CEL profile — a disallowed function call, a comprehension macro, a map/struct literal, a bare identifier that is not a state path or def, a reserved internal token, or visited(…) used outside a condition slot. A {{…}} interpolation that is not a state path, a def @ref, or a declared host token (the message lists them; an undeclared bare name is told to declare it in a plugin’s hostTokens: export).

Spec: dsl §8.4, dsl 0.21.0 §7a.1, dsl 0.50.0 §4.2

A condition’s types cannot mean what is written: a comparison between a bool, a number and a string (visited('x') > 2, run.oil == true, run.day == 'monday'), an ordering of anything but numbers (run.hour >= 'h03'), a non-bool operand of && / || / ! / ?: or condition, arithmetic that cannot be computed, or an operand of the integer modulo operator % that is not an integer.

Spec: dsl 0.24.0 §1, dsl 0.28.0 §1

A ::cg directive uses the removed full attribute; only a project-declared cgLayout member written as layout= can replace it, so it must be migrated by hand.

Spec: dsl 0.37.0 §3.3, dsl 0.37.0 §4

The project’s chapters: is malformed — not a list of { on, scenes } chains, a key that is neither (a chain names its occasion with on:, not occasion:), an entry that is no scene id, a scene listed twice, two chains on one occasion — or the manifest still uses the retired sequence: key; or a chain names an occasion no plugin declares (or, shape-only, a near-miss of one other beats answer), lists an id no scene declares (a bundle beat, lore entry or document is named as such), lists a scene whose own on: answers another occasion, or, on an occasion raised for a target, lists a scene with no target: (it would play for every target). A malformed chain is not applied; the other chains are. Reported at the manifest line — a missing target: at the scene’s id: — and the documents are still checked.

Spec: dsl 0.28.0 §4

A construct requires a semantic capability the selected engine does not support.

Spec: dsl 0.33.0 §4

A <branch> or <hub> declares two <choice> elements with the same id, but choice ids must be unique within their branch or hub; or a branch or hub with prompt= has a <choice id="prompt">, whose lineId would be the prompt’s ({prefix}.{branchOrHubId}.prompt) — rename the choice.

Spec: dsl §11.1, dsl 0.47.0 §3.1

A guard or condition reads a reserved choice-log path, which may not be read from a guard or condition.

Spec: dsl §9.6

An input file was read but is not valid for the command: malformed JSON or YAML, the wrong kind of document, or an unsupported version.

Spec: dsl 0.43.0 §4.3

A file or directory the command names cannot be read or written.

Spec: dsl 0.43.0 §4.3

The command line is invalid: an unknown command or argument, a missing required argument, or an invalid value or combination.

Spec: dsl 0.43.0 §4.3

Two clips in the same <track> have overlapping [at, at+duration) intervals.

Spec: dsl §11.4

A single <track> clip carries both at (an absolute timeline position) and delay (a relative nudge), which are mutually exclusive on one clip.

Spec: dsl §7.5, dsl §11.4

A clock: declaration is malformed (a missing field, a last.slot not in slots, days: 0, both last and days), or a project declares more than one clock:.

Spec: dsl 0.24.0 §1

A lute play/lute test advance: step runs while a finite clock has ended, or starts past its last position — the clock already raised its last dayEnd and stopped, so play a newRun or end the script.

Spec: dsl 0.27.0 §4

A /* … */ block comment ran to the end of the file without a closing */.

Spec: dsl §4.2

A ::use invocation reaches compilation still unresolved — used inside a <timeline> clip (not allowed), naming no resolvable component, or with args that do not match the component’s params — a case the check gate should already have caught.

A CEL slot or beat when fails to expand at compile time — an expansion cycle, an unknown def, or an arity mismatch.

The compiler reached a state it cannot recover from; this is a Lute bug, so please report it with the document that triggers it.

A ::use invocation’s arguments do not match the named component’s declared params — an unknown argument, a missing required param, a value of the wrong type, an incompatible default, or (for a speaker param) an argument that is not a literal cast id.

Spec: dsl §13, dsl 0.24.0 §3, dsl 0.26.0 §3.3

A component body contains a construct that is not presentational — a ::set, <branch>, <hub>, <timeline>, <objective>, <on>, ::assert, or ::retract that writes or affects state, or a ::use of an effectful inner component without declaring effects: true itself.

Spec: dsl 0.4.0 §6.2, dsl 0.24.0 §4

A chain of ::use invocations expands into a cycle across components.

Spec: dsl §13

Two different component files declare the same component: name.

The same component and instance key occur twice in one immediate expansion owner.

Spec: dsl 0.36.0 §2.3

instance is empty, exceeds 64 characters, uses a non-ASCII token, or appears more than once as an identity attribute on one ::use.

Spec: dsl 0.36.0 §2.3

A component file cannot be read, resolved, or parsed cleanly — an unresolvable components: import path, a missing component: name, or a malformed params: entry.

A component body reads or writes ambient state directly — a CEL reference to a state path, a fact query, or a directive that declares state/bridge-result writes — instead of binding it through a param.

Spec: dsl 0.4.0 §6.1, dsl 0.4.0 §6.2, dsl 0.24.0 §4

lute tag on a component whose users’ capability snapshots disagree on whether a directive it calls has text attributes: one user activates the plugin that declares them, another does not. A call has one localization identity, so lute tag gives it no code and leaves the component untouched; reported at the call, with a use of each kind related.

Spec: dsl 0.51.0 §5.3

A ::use’s component attribute names a component absent from the resolved components: table.

Spec: dsl §13

The project’s after prerequisite graph contains a cycle, so no evaluation order can satisfy every after clause simultaneously.

Spec: dsl §4.1

Two documents (or a document and a derived key) share the same document id in the project’s shared id namespace.

Spec: dsl 0.15.0 §2, dsl 0.19.0 §2.1

An after prerequisite formula’s atom count exceeds the defensive cap, a pattern typical of a pathological or machine-generated formula rather than one an author types by hand.

Spec: dsl §4.1

An after prerequisite formula uses a construct outside the restricted prerequisite profile — anything other than visited(…)/completed(…)/active(…) atoms combined with &&/|| and parentheses.

Spec: dsl §4.1

An after prerequisite formula’s visited(K)/completed(Q)/active(Q) atom names a node that does not exist anywhere in the project.

Spec: dsl §2.3, dsl §4.1

A scene, quest, or beat is provably unreachable — no evaluation order can ever satisfy its after prerequisite.

Spec: dsl §4.1, dsl §4.2

A project constraint declaration is malformed: it has an unknown key or kind, misses a required field, names a bad node, or repeats an id.

Spec: dsl 0.34.0 §5.1

A project constraint is violated; the diagnostic carries the verdict’s evidence, bounded scope when applicable, and causal spans.

Spec: dsl 0.34.0 §5.2

A content line’s attributes are written with […] instead of the required {…} (the same delimiter ::directive{…} uses).

Spec: dsl §2.1

A content-shaped line (@speaker…, ::directive, a <tag>) appears before the document’s first ## section heading, since content only belongs inside a section body.

Spec: dsl 0.5.0 §2.1, dsl 0.6.0 §3.3

A context position query has an invalid coordinate or falls outside the source file.

Spec: dsl 0.36.0 §3.3, dsl 0.36.0 §8

A context target key is unknown or ambiguous in the project graph.

Spec: dsl 0.36.0 §3.1, dsl 0.36.0 §8

An ::assert/::retract payload, a facts: entry, or a rules: term uses a compound/function term such as f(g(x)), but facts and rule terms admit only ground identifiers/booleans.

Spec: dsl 0.3.0 §7.1

A rule-body CEL guard reads the fact store or narrative time via holds, count, validAt, or now, which a guard is not allowed to depend on.

Spec: dsl 0.3.0 §7.2, dsl 0.3.0 §7.3

A facts:/rules: entry is not a quoted string, or a quoted facts:/rules: string fails to parse as a well-formed ground fact or rule.

Spec: dsl 0.3.0 §4, dsl 0.3.0 §5

A rule’s negated atom, != comparison, or CEL guard reads a variable that no positive body atom binds first, so the rule cannot be safely evaluated.

Spec: dsl 0.27.0 §3, dsl 0.24.0 §3

A rule’s negation edge closes a cycle in the predicate-dependency graph (including p :- not p), so the ruleset cannot be stratified.

Spec: dsl §7.2

A defs: entry is malformed — not a CEL string or a { type?, params?, cel } mapping, an unknown key, a missing cel:, or a type: that is neither inferable from the body nor consistent with it.

Spec: dsl 0.21.0 §7b

A manifest’s defaults: block names a key outside the closed defaultable-frontmatter set, or gives a defaultable key a value of the wrong shape.

Spec: dsl 0.10.0 §6.1

A content line sets more than one of the mutually exclusive delivery flags mono, os, vo.

Spec: dsl 0.2.2 D7

A delivery flag (mono/os/vo) is given a value, but a delivery flag is bare and takes none.

Spec: dsl 0.2.2 D7

A narrator content line carries a delivery attribute, but narration takes no delivery.

Spec: dsl 0.1.0 §12.1

Two or more plugins’ depends declarations form a cycle, so their activation order cannot be resolved.

A plugin’s depends names another plugin id that is not installed in the project.

A plugin’s depends names an installed plugin whose version does not satisfy the declared version range.

A relation is declared derive: true but also declares a write tier:, though a derived relation has no write tier of its own.

Spec: dsl 0.3.0 §4, dsl 0.3.0 §7.1

A rules: entry’s head names a relation that is not declared derive: true (a base relation, a reserved relation, or an entity-kind name), though only a derived relation may be a rule head.

Spec: dsl 0.3.0 §7.1, dsl 0.3.0 §3.1

Content asserts or retracts a relation declared derive: true, though a derived relation is computed by rules: and must not be written directly.

Spec: dsl 0.3.0 §5

A lute.project.yaml diagnostics: entry cannot apply: its key is an error code (an error is never re-levelled), a lint rule (set in lute.lint.yaml rules:) or no diagnostic code at all, its level is not one of off, info, warn, error, or its paths is not a non-empty list of project-relative globs. The entry is dropped and the manifest is invalid.

Spec: dsl 0.50.0 §6.1

A diff side cannot be read, safely materialized, or built into a complete project model.

Spec: dsl 0.36.0 §4, dsl 0.36.0 §8

A semantic diff cannot produce a complete project model for one side.

Spec: dsl 0.36.0 §4, dsl 0.36.0 §8

$ (the match subject) is used outside a <match> block, where it is not valid.

Spec: dsl §8.2

A project’s own enums:/entities: declaration (inline or reached through uses:/extends:) names a domain that a plugin or the core already declares, though a domain name must have exactly one source.

Spec: dsl 0.3.0 §3, dsl 0.9.0 D-D

One name is declared both as an enums: domain and as an entity kind — in one document or across the schemas a document merges. Enums and entity kinds share one domain namespace, so the kind’s members would silently replace the enum’s wherever the name types a value.

A content-line emotion/action slot, an entity attribute, or an implicit anchor read names a domain that no enums:/entities: declaration defines.

Spec: dsl 0.9.0 D-C, dsl 0.9.0 D-D

A <branch id> or <hub id> repeats an id already used by another branch or hub in the same episode, since branch and hub ids share one uniqueness domain.

Spec: dsl §11.1, dsl §7.3.2

Two content lines from the same speaker share the same :line code=, though a (speaker, code) pair must be unique — it is the voice-key/i18n identity join key. Likewise two calls of one directive with text attributes in one identity scope sharing code=: a (directive, code) pair is the localization identity of its text attributes.

Spec: dsl §12, dsl 0.51.0 §5.3

Two <track>s in a <timeline> share the same track key.

Two lines whose plain text (inline modifier markup removed) differs compile to the same voiceKey, so one recording would voice both — usually because the voiceKey template lacks {prefix} and collides across documents.

Spec: dsl 0.37.0 §3.6

The engine matrix and execution artifact are outside the accepted IR version line.

Spec: dsl 0.33.0 §4, dsl 0.33.0 §5

The engine capability matrix is unreadable or malformed.

Spec: dsl 0.33.0 §4

An ::set writes a state path declared owner: engine, though the engine writes such a path and content may only read it.

Spec: dsl 0.22.0 §1.2

The selected engine does not support a semantic capability required by the artifact.

Spec: dsl 0.33.0 §4

An id is listed as a member of two different entity kinds’ members:, though an id must belong to exactly one kind unless one kind is declared a subsetOf: the other.

Spec: dsl 0.3.0 §3.1, dsl 0.24.0 §3

An entity kind declaration is malformed — it declares neither or both of members:/open:, has an unknown key, lists a member more than once, or a labels:/add: entry names a member the kind doesn’t have or targets an open:/unknown kind; a YAML list must be rewritten as { members: [...] }.

Spec: dsl 0.3.0 §3.1, dsl 0.26.0 §2.3, dsl 0.27.0 §2, dsl 0.46.0 §2.2

A <entry> attribute has a malformed shape — a non-quoted-string value, a missing or invalid id, or a series=/order= authored under a document-level series:.

Spec: dsl 0.19.0 §3, dsl 0.19.0 §2.1

Two <entry> elements share the same id, though entry ids must be unique across the document (and project-wide under whole-project check).

Spec: dsl 0.19.0 §3

Two <entry> elements resolve to the same (series, order) position, though each position in a series must name exactly one entry.

Spec: dsl 0.19.0 §2.1, dsl 0.19.0 §3

A lore entry’s when eligibility guard provably never holds, so the entry can never be presented.

Spec: dsl 0.20.0 §5

A domain’s default: value is not one of its own declared members.

Spec: dsl 0.9.0 D-D

A domain’s exits: list names a value that is not one of its own declared members.

Spec: dsl 0.9.0 D-D

A domain’s labels: key names a value that is not one of its own declared members.

Spec: dsl 0.24.0 §1

A domain occupies a slot (such as anchor) that requires default: or exits: semantics, but the domain (or an entities: kind standing in for it) declares neither.

Spec: dsl 0.9.0 D-D

A musicPlayback domain’s stops: list names a value that is not one of its own declared members.

Spec: dsl 0.40.0 §2.2

A domain declares default: or exits:, but the slot it fills has no meaning for that semantics.

Spec: dsl 0.9.0 D-D

An extends-base entity kind, relation, or enum is re-declared by a child schema with a members/open shape flip, a missing base member, or a decl that otherwise differs from the base, though a re-declaration must be a legal superset refinement.

Spec: dsl 0.3.0 §4.1

An imported schema’s state path is re-declared by a deeper extends base or the scene’s inline state: with a different type, though persisted state must keep a stable type.

Spec: dsl §9.2

A rule guard, indexed query, or content query compares/binds a relation argument against a variable that ranges over no closed kind, or over a kind that shares no members with the argument’s declared domain.

Spec: dsl 0.27.0 §3, dsl 0.3.0 §3.1

An ::assert{A(x)} targets arguments where a fact of a mutually exclusive relation already holds, though the two relations are declared exclusive on those arguments.

Spec: dsl 0.25.0 §1

A fact-query call (holds, count, countDistinct, or validAt) does not use the required 0.32 list form name('relation', ['arg', …]).

Spec: dsl 0.32.0 §2

Content asserts or retracts an app-tier base relation, though it is engine-owned/read-only to content, exactly like app.* scalar state.

Spec: dsl 0.3.0 §5, dsl 0.3.0 §9.5

A flag attribute (<choice once>/exit, <objective optional>, <beat also>) is given a value other than true/false; a flag is written bare, and a beat/entry once period on a choice is refused.

Spec: dsl 0.28.0 §1

The formatter cannot parse or preserve the requested file.

Spec: dsl 0.36.0 §1, dsl 0.36.0 §8

A formatter check found noncanonical bytes in the requested file.

Spec: dsl 0.36.0 §1, dsl 0.36.0 §8

A document’s frontmatter key, declared by an active plugin, holds a value whose shape does not match the plugin’s declared type for that key.

A document uses a construct its document kind’s grammar forbids in that context — such as a <quest> in a scene, anything but <on>/<objective> at a quest’s top level (a quest runs only its handlers and objective bodies), <hub>/<timeline> anywhere in a quest, or staging/choices in a lore <entry>.

Spec: dsl 0.2.0 §3.3, dsl 0.2.0 §6.7, dsl 0.19.0 §4, dsl 0.52.0 §4

A <hub> can never exit: it lacks both an unguarded (when-less) exit choice and the guarantee that every choice is once so the eligible set provably empties.

Spec: dsl §7.3.2, dsl §11.1.3

A project’s identity.lineId/identity.voiceKey template names an unknown {token}, or resolves to an empty string, or the lineId template’s literal text contains ~, which is reserved for directive text identities ({prefix}~{tag}~{code}~{attr}).

Spec: dsl 0.8.0 §9, dsl 0.51.0 §5.3

A body # heading: it is no document title. Put the value in frontmatter title:, the only document title.

Spec: dsl 0.37.0 §3.1

A {{…}} marker in line text directly follows an odd run of literal {, which compiled text cannot tell apart from the marker — or a marker in line text or a label opens on a literal brace run ({{{run.a}}: its expression begins with {) — or a ::use argument ending in a plain {{ is spliced right before one and swallows it. Put a character between the braces and the marker, or show each brace from a string state path; in an argument write a literal {{ as \\{{.

Spec: dsl 0.52.0 §3.1, dsl 0.53.0 §8

A {{@def}} interpolation cannot inline into one standalone expression — its body has an expansion cycle, reads $, or fails to parse.

A {{…}} interpolation is not closed before the end of the line.

Spec: dsl §7.6

A <choice>’s into= attribute is missing, is not a run.<path> string literal, or names a bare run or non-run.* path.

Spec: dsl 0.6.0 §2.2

A <choice>’s into="run.<path>" names a path that is not declared in the run schema, so it cannot silently create a field.

Spec: dsl 0.6.0 §2.2

A <choice>’s into= run-record sugar has a value attribute that is missing, not a true/false literal for a bool path, or incompatible with the target path’s declared type.

Spec: dsl 0.6.0 §2.2

lute run received an execution IR that still carries a field 0.37 removed or renamed (such as addr, capabilityVersion, recordKey, shots, a flattened wait/duration/delay/at/timeline stamp, provenance.injected, a per-kind field such as camera zoom, cg.full, cg/video/music action, music.track or sfx.name, an option label, or an old line role such as monologue), or a command with no position. The message names the 0.37 replacement. Recompile the source with the current toolchain.

Spec: dsl 0.37.0 §4, dsl 0.37.0 §5.3

A ::jump{to} without max names a label that is not forward of the ::jump in document order. A jump goes forward unless it carries max: ::jump{to="again" max="3"} jumps back at most 3 times; to offer choices again, use a <hub>.

Spec: dsl 0.12.0, dsl 0.51.0 §3.1

A ::jump targets a label in a body that runs as its own range — a <hub> option or <return> body, an <on> or <objective> body, an entry or a beat — from outside that body. A jump stays in its own body or leaves <hub> option and <return> bodies for a label in a body around them (after the hub); <choice> bodies of a <branch> and <match> arms are part of the body around them, and a scene’s sections are one body.

Spec: dsl 0.52.0 §5.1

A forward ::jump from outside a loop (a ::label and a later ::jump{to max} back to it) lands on a label inside the loop after its head; a loop is entered only at its head label. When the jump ends one <choice> body and no other jump targets the label, the message suggests moving the block into that option’s body.

Spec: dsl 0.51.0 §3.2, dsl 0.53.0 §9.4

Two loops overlap without nesting: the later loop’s head label lies inside the earlier loop, after its head, but the later loop ends after the earlier one. Loops nest or stay apart; close the inner loop before the outer one jumps back.

Spec: dsl 0.51.0 §3.2

A bounded ::jump{to max} loops back to a label outside the body it runs in: a loop may pass only through <choice> bodies of a <branch> and <match> arms, never out of a <hub> option or <return> body, an <on> or <objective> body, a quest, an entry or a beat. A document’s ## sections are one loop scope.

Spec: dsl 0.51.0 §3.2, dsl 0.53.0 §9.2

The max of a ::jump is not a literal integer from 1 to 99 (a loop bound is static, so an @ref is refused too), or it sits on a forward jump, where it means nothing. A value that is not an integer at all is E-ATTR-TYPE.

Spec: dsl 0.51.0 §3.1

A ::jump{to} names a label that no ::label anywhere in the document declares.

Spec: dsl 0.12.0

A root document declares no kind: frontmatter key and the manifest’s defaults: also names none, so the document’s kind cannot be resolved.

Spec: dsl 0.2.0 §3.1, dsl 0.19.0 §2, dsl 0.10.0 §6.3

An entities: block declares the same entity kind name twice, two schemas declare one kind differently, or a name is declared as both an entity kind and a relation.

Spec: dsl 0.3.0 §4

A translated text — a line, an option label, a prompt or a directive text attribute — does not show its source’s {{…}} markers: a marker does not parse (a marker opened on a literal brace, {{{run.a}}; at lute loc import also a line’s {{ with no }}, which compile reports as E-L10N-MODIFIERS), or the markers are not the source’s, each as often (any order; the spaces at a marker’s edges do not count, a space inside it or a format hint does). The runtime would show such a marker verbatim, so the translation is not merged; lute loc import refuses a marker that does not parse.

Spec: dsl 0.53.0 §8.1

A line translation’s inline modifiers (names, span/leaf form, and attributes) differ from its source line’s, or its markup does not parse, so the translation is not merged.

Spec: dsl 0.37.0 §6

A label name — a ::label{name} — is declared more than once anywhere in the document; every label shares one document-wide namespace.

Spec: dsl 0.12.0

A content line uses the old : speaker sigil, which @ replaced — write @speaker{…}: text instead.

Spec: dsl §7.1

A code= on a content line or on a directive with text attributes contains ~, the separator of a directive text identity ({prefix}~{tag}~{code}~{attr}); lute tag never writes one.

Spec: dsl 0.51.0 §5.3

Two localization units of the project — lines, choice and hub options, prompts, directive texts — compile to one final lineId (reported at the later unit, the first one related), as a lineId template without {prefix} can produce across documents. A lineId keys one translation, so lute loc import and --locale-bundle could not tell them apart. Whole-project check and compile --project.

Spec: dsl 0.51.0 §5.3

lute.lint.yaml is malformed — a wrong-typed or unknown top-level key, a bad rule override, or a custom rule id that collides with a core rule id. Since 0.49.0 it also covers an asset-exists options.providers key that is none of the selector shapes (<tag>, <tag>.<attr>, @<attr>). A rules: id that is a checker code is named as one: a warning’s level is set in lute.project.yaml diagnostics:, and an error cannot be re-levelled. Since 0.51.0 it also covers a custom rule whose keys do not fit its target: when on target: pair, a pair rule without open or close, or open, close, inside or scope on any other target.

Spec: dsl 0.49.0 §7.3, dsl 0.50.0 §6.4, dsl 0.51.0 §6.1

A lint rule’s predicate — when, or a pair rule’s open, close or inside (named in the message) — fails to parse or resolve, or is mistyped, so that rule is skipped for the document.

Spec: dsl 0.51.0 §6.1

A plugin or custom lint rule declaration is malformed, such as reusing a core rule’s id.

lute compile --locale-bundle failed to merge a locale import file — bad syntax, a row with an empty locale, or a duplicate lineId for the same locale.

A logic block holds a child it does not admit (a <branch> or <hub> takes only <choice>s, a <match> only <when> and <otherwise>), a <choice>, <when>, <otherwise>, <track> or <reward> stands outside the block it belongs in, or a <reward> is not self-closing.

Spec: dsl §7.3, dsl §7.3.2, dsl 0.16.0 §2

A directive’s declarative lower: { record, fields } mapping names a target field the record does not have, or maps a field it cannot legally write.

A directive’s lower: { record: … } names something outside the closed set of staging record kinds declarative lowering supports.

lute.project.yaml cannot be read as a manifest: it does not parse, is not a mapping, lacks defaultProfile:, or a value has the wrong shape.

Spec: dsl 0.28.0 §1

lute.project.yaml has a key it does not define — at the top level, in a profile, or in identity: — or a key another layer owns (a schema key such as terminal:, a document key that belongs under defaults:).

Spec: dsl 0.28.0 §1

A <match> contains more than one <otherwise> arm, though at most one is allowed.

Spec: dsl §11.2

A <when is=…> arm sits in a <match> with no subject=, so its literal has no subject to be compared against; add subject= to the <match>, or write the arm as test=.

A <match subject> subject, directly or via an @def it expands to, is a fact query (holds/count/validAt), which match subjects may not be.

Spec: dsl 0.27.0 §2, dsl 0.3.0 §8

A state path is read where it may not yet be set — no default, no dominating ::set, and no guard proves it is set.

Spec: dsl §9.4

A document’s id: frontmatter value is not a dotted id: names (letters, digits, _ or -, not starting with -) joined by ..

Spec: dsl 0.30.0 §1

A required frontmatter key — such as character/season/episode, or an id: — is missing from a document that must declare scene identity.

Spec: dsl 0.15.0 §2, dsl 0.15.0 §4

A document’s frontmatter is not valid YAML, or parses as YAML but is not a mapping.

A document declares a top-level meta key that is neither a core key nor owned by an active plugin, or one reserved for another document kind.

A frontmatter value has the wrong shape — a malformed extra: mapping or key, a series: that is not a name, a malformed cast:/enums:/terminal: entry (in terminal:’s long form, a key other than when/persists or a persists that is not true/false), persists: true on a terminal: that reads only run state (its ending cannot outlive the run), or a bad effects: flag.

Spec: dsl 0.15.0 §3, dsl 0.19.0 §2.1, dsl 0.23.0 §7, dsl 0.29.0 §5

A directive is missing an attribute its declared schema requires, a <reward> does not author an attribute its reward kind declares required: true, or a directive, content line, <branch>, <hub> or <choice> does not author a plugin stamp declared required: true on its surface (on:); a stamp is never injected and a reward attribute’s default: does not satisfy required, so neither counts as authored.

Spec: dsl 0.50.0 §3.4, dsl 0.52.0 §7.2

A --mock/mocks/*.yaml entry declares no file:, names a file: path that does not exist or is not a .lute document, or disagrees with the document named on the command line.

Spec: dsl 0.10.0 §8

A {mono} line’s document resolves no point of view (no frontmatter pov: and no project defaults.pov) and its speaker is not in monoSpeakers:. A component line is judged at each ::use site, in the caller’s context.

Spec: dsl 0.37.0 §3.4

A {mono} line’s speaker is neither the document’s effective point of view (pov:, else the project’s defaults.pov) nor in its effective monoSpeakers: list. A component line is judged at each ::use site, in the caller’s context.

Spec: dsl 0.37.0 §3.4

A <match> has no <otherwise> and its subject’s domain is not fully covered by the <when> arms — the message names the missing values or the first uncovered gap.

Spec: dsl 0.18.0 §4, dsl §11.2

Two required <objective>s of one <quest> name done predicates over the same state path whose solution sets can never both hold.

Spec: dsl 0.10.0 §5.2

An <objective id> is declared more than once within the same <quest>.

An <objective> within a <quest> has no id.

An <objective> has an empty done completion predicate and no quest= reference to delegate its completion.

An <objective> carries both a quest= subquest reference and a non-empty done= predicate, which are mutually exclusive.

An <objective title> holds {{ — a marker, escaped or not — but a quest UI shows the title as written, so it takes no {{…}}. Write the title as plain text and show a value that changes in a line.

Spec: dsl 0.52.0 §6.7

A required <objective>’s done predicate can never decide true, or its <objective quest="…"> references a subquest that is itself unreachable.

Spec: dsl 0.4.0 §5.3

A lute play step raises an occasion while its raisedWhen gate is false, or after the schema’s terminal: condition already holds, so the engine would not actually raise it.

Spec: dsl 0.27.0 §4

A beat’s or entry’s on= names an occasion that no resolved plugin declares.

Spec: dsl 0.21.0 §2

An <on> has no event attribute — every <on> must be anchored to a discrete event.

Spec: dsl 0.2.0 §4.1

A staged patch introduces a new check or project error.

Spec: dsl 0.36.0 §5.2, dsl 0.36.0 §8

A patch edit is malformed, outside its target, overlaps another edit, or fails its escape-hatch span assertion.

Spec: dsl 0.36.0 §5.1, dsl 0.36.0 §5.2, dsl 0.36.0 §8

A patch would leave a .lute file it region-formatted non-canonical: a file that was lute fmt --check clean would not be, or formatting the touched lines again would change them. Nothing is written; the message names the file.

Spec: dsl 0.47.0 §5.1

A patch violates a requested preserve claim, including an ambiguous reward or component match.

Spec: dsl 0.36.0 §5.3, dsl 0.36.0 §8

A patch base project or asserted file revision differs from the current revision.

Spec: dsl 0.36.0 §5.2, dsl 0.36.0 §8

A patch target is unknown, ambiguous, or has no editable source anchor.

Spec: dsl 0.36.0 §5.1, dsl 0.36.0 §8

A name has a character outside the name rule (letters, digits, _ or -, not starting with -): a state path segment; a quest, objective, entry, branch, hub, choice or mark id; a relation, enum or entity kind; an enum or entity member. A def or def param is not an identifier (a letter or _, then letters, digits or _): it is read bare, as @name or in the def’s body. Or a condition writes a name that is not an identifier after a . (quest.zero-coke-001.state), which CEL reads as a subtraction; the message names the bracket spelling (quest["zero-coke-001"].state).

Spec: dsl 0.30.0 §1, dsl 0.30.0 §2, dsl §8.4

A directive invokes a bridge service/operation the effective bridges permission ceiling forbids.

A ::set/::assert/::retract or plugin directive is forbidden by the effective directives permission ceiling.

A fact write — ::assert/::retract, a plugin effect, or a seed fact — targets a relation the effective factWrites permission ceiling forbids.

--permission-profile <name> was passed without a loaded lute.project.yaml from --project <DIR> to resolve the profile against.

A <quest> is declared where the effective quests permission ceiling forbids quest declarations.

A <reward> is declared where the effective rewards permission ceiling forbids reward declarations.

A state write — a ::set, a choice into=, a state/plugin default initialization, or an unresolved plugin write path — targets a path the effective stateWrites permission ceiling forbids.

A directive uses the removed persist attribute — into= alone records the run fact.

Spec: dsl 0.6.0 §2.2

A plugin’s assetKinds export declares a segment type outside the four a segment position admits — enum, number, string, or providerRef.

Two active plugins declare the same directive, event, reward kind, occasion, cast id, or bridge operation, or stampAttrs entries of one name on overlapping surfaces (an entry without on: overlaps every entry; the message names the shared surfaces), or a plugin declares a host token another plugin or lute.core (userName) declares; the first declaration is used.

Spec: dsl 0.50.0 §3.2, dsl 0.50.0 §4.1

A plugin package declares the same id more than once within one export kind, or two stampAttrs entries of one name whose on: surfaces overlap (an entry without on: overlaps every entry; the message names the shared surfaces); the first declaration is used and the rest of the project is still checked.

Spec: dsl 0.50.0 §3.2

A plugin directive declaration uses a semantics: flag outside the closed vocabulary, declares the same attribute name more than once, or declares an attribute default: that is not a value of the attribute’s type (an integer defaulting a double is one); or a directive attribute or stampAttrs entry is typed list, map or record, which no authored attribute value can satisfy (structured values are not supported yet: give each field its own attribute, use a text attribute for player-visible text in several languages, or write a list of options as <choice> elements); or a stampAttrs entry is typed text; or a directive whose lower: builds a staging record or runs a builtin hook declares effects.raises, which no such lowering carries to the host (only a plugin record does) — the raises are dropped.

Spec: dsl 0.49.0 §3.2, dsl 0.51.0 §4.2, dsl 0.51.0 §5.1, dsl 0.51.0 §7

A plugin export file or directory could not be read due to an I/O or encoding failure.

A key in a plugin’s plugin.yaml or one of its export files is not one that file takes (with the key meant, e.g. dependencies → depends), or plugin.yaml declares a kind: other than capability. A reward kind’s effects.writes adds that a reward’s state write is credits:.

Spec: dsl 0.28.0 §1, dsl 0.50.0 §5.1

A plugin package’s plugin.yaml manifest is missing, is not valid YAML, or names no id/version/kind/exports.

A profile activates a plugin id that is not installed under the plugins directory, or whose package failed to load.

Spec: dsl §11

A plugin manifest’s exports: entry names a path that does not exist on disk.

Spec: dsl §4, dsl §11

A plugin activation’s option value does not match the type its manifest declares for that option.

Spec: plugin Appendix C1

A plugin activation sets an option name the plugin’s manifest never declares.

Spec: plugin Appendix C1

A plugin export file is not valid YAML or holds a value of the wrong shape (named with its line and the shape the key takes), or a directive’s effects.writes/effects.asserts/effects.retracts entry names an attr the directive never declares (or an assert uses _), or a stampAttrs entry’s on: is empty, not a list of surface names, or lists a surface twice, or the entry is required: true without on:, or a reward kind’s attrs: entry reuses a name <reward> already has (id, kind, target, amount, when, outcome), repeats a name, declares a default: not of its type or a list, map or record type, or a reward kind’s effects: declares no effect (none of asserts:, retracts:, accepts: or raises:), a fact effect reads an @attr that is neither @target nor an attribute the kind declares, or asserts _, an accepts entry is neither @target nor a quest id, a raise targets an @attr that is neither @target nor an attribute the kind declares, or a kind with target: { forbidden: true } reads @target (a raise for @target included), or an effects.raises list is empty, an entry is not a mapping of occasion and optional target, its target is neither @<attr> nor a dotted target, or (on a directive) its @<attr> names no attribute of the directive, or an occasion’s raisedBy is not declared, or a hostTokens name is not an identifier (letters, digits and _, not starting with a digit) or its type is not string, int or { enum: [...] }, or a type: text sits anywhere but a directive attribute (a plugin option, an occasion payload, a reward-kind attribute, a bridge result, a state shape, a nested { list: text }), or a directive’s text attribute is on a directive with lower: or bridge: (no localized text would reach the host), declares a default: (which has no translation), or sits beside a declared attribute named code (the identity attribute of a directive with text attributes), or a lints/ rule’s keys do not fit its target (when on target: pair, a pair rule without open or close, or open, close, inside or scope on any other target).

Spec: dsl 0.27.0 §2, dsl 0.27.0 §4, dsl 0.28.0 §7, dsl 0.50.0 §3.2, dsl 0.50.0 §4.1, dsl 0.50.0 §5.1, dsl 0.51.0 §4.1, dsl 0.51.0 §4.2, dsl 0.51.0 §5.1, dsl 0.51.0 §6.1, dsl 0.52.0 §7.1, dsl 0.52.0 §7.3

A directive’s or reward kind’s effects.raises entry names an occasion no active plugin declares (with a did-you-mean, or the installed but inactive plugin to declare in depends:), gives a target to an occasion raised for none or none to one raised for a target, targets an @attr of a domain occasion whose type is not { entity: <the domain's kind> } (on a reward kind: whose target: contract is not), or names a literal target outside the occasion’s <prefix>.<member> shape or members:. Judged at plugin assembly, where every active plugin’s occasions are known; the entry is dropped and its siblings land.

Spec: dsl 0.51.0 §4.2

A plugin declares a name the core language owns: a directive named like a core statement (set, assert, retract, accept, use, body, cut), a core block tag (scene, on, quest, objective, match, branch, hub, choice, when, otherwise, entry, beat, timeline, track, reward, return) or a lute.core directive (end, mark, bg, …); an event or occasion named like an engine lifecycle event (questComplete, …) or a play step key; a cast id narrator; a host token named like a state root or a CEL literal ({{run}} would read as a state root). Reported at the declaration’s file and line.

Every reserved name, where it is refused and what to write instead: Reserved names.

Spec: dsl §10, dsl 0.28.0 §1, dsl 0.50.0 §4.1

A non-core plugin’s stampAttrs export or a directive’s attrs declares an attribute name (at/duration/delay/wait/timeline/timing/provenance/source) that the core stamp already owns. Plugin stamps compile under the record’s nested stamps object, but these names stay reserved: they would read as the core stamp. Also a stampAttrs entry scoped with on: to a surface that owns an attribute of the same name (prompt on branch, text on choice, code on line, a directive’s own attribute, code on a directive with a text attribute), so the stamp could never be read there.

Spec: plugin §14, dsl 0.50.0 §3.2, dsl 0.51.0 §5.1

A stampAttrs entry’s on: names a surface that is not line, branch, hub, choice or a directive of the resolved profile (with a did-you-mean, or the installed but inactive plugin to declare in depends:), or a directive with no stamp carrier (jump, label, clear). The entry is dropped; its siblings still load.

Spec: dsl 0.50.0 §3.2

A directive binds an attribute to an asset kind that no active plugin declares.

Spec: plugin §7

A plugin manifest’s exports: key is not one of the export kinds (with a did-you-mean); the old spellings rewardkinds/assetkinds/stampattrs name rewardKinds/assetKinds/stampAttrs.

Spec: plugin §4, dsl 0.28.0 §6

A rewardKinds: entry pins target: { provider: <name> } to a provider no active plugin declares.

Spec: dsl 0.16.0 §4

A {{n:plural(…)}} hint whose forms are not a bare singular and a bare plural separated by | — quoted forms, a , separator, a missing or empty form.

Spec: dsl 0.27.0 §7, dsl 0.28.0 §5

A profile’s extends chain loops back to itself.

Spec: dsl §11

The project selects a profile name that lute.project.yaml never declares.

Spec: dsl §11

The editor could not load the document’s lute.project.yaml (a malformed or unreadable project manifest).

A <quest id=…> repeats an id already used in this document, across its import graph, or project-wide.

Spec: dsl 0.2.0 §6.3

A <quest> has no id attribute.

Spec: dsl 0.2.0 §6.3

A subquest is referenced as a child by <objective quest=…> from two different parent quests, but a quest may have at most one parent.

An <objective quest=…> names a child quest id that no quest in the project defines.

A state: declaration’s path collides with an implicitly-declared reserved quest field (quest.<id>.* / objectives.<oid>.done).

Spec: dsl 0.2.0 §5.2

An ::set writes a reserved, engine-populated path — quest.<id>.state, objectives.<oid>.done, an entry.* path, prev.run.*, prev.season.*, or clock.*.

Spec: dsl 0.2.0 §5.4, dsl 0.19.0 §5

Quests’ start conditions and in-script accepts (::accept, a reward’s accepts) wait on each other around a cycle that no source outside it enters, so none of them can ever start; the path names each edge kind, and the error is at the least quest’s start, or its id when it has none. Start one of them from something outside the cycle, or let the host grant one with accept="external".

Spec: dsl 0.49.0 §6.1, dsl 0.53.0 §7.3

A quest’s start reads the quest’s own state (quest.<id>.*), which has no value before the quest starts; a quest only the host grants is written accept="external" without a start, and a condition the host waits for is written follows="…" (host policy: Lute carries it, analysis reads it).

Spec: dsl 0.49.0 §6.2, dsl 0.53.0 §7.4

A subquest’s effective tier differs from its parent quest’s tier.

Spec: dsl 0.23.0 §6

The parent-child edges induced by <objective quest=…> close a cycle, including a quest naming itself as its own child.

A <quest> can provably never complete because its start guard always decides false or its fail guard always decides true.

Spec: dsl 0.4.0 §5.3

A declared raise’s resolved target — the call’s attribute value (an @def folded to its constant) or its declared default:, a reward’s target=, or a literal — lies outside its occasion’s members: (a literal: outside its entity kind), or no scene or beat answers the occasion for it (with a did-you-mean). A target that reads occasion.target is bound by the runtime and not judged; an attribute with no value and no default: raises nothing. A call in a component body is judged at each ::use. Whole-project check only.

Spec: dsl 0.51.0 §4.3

A @name(args) call to a def passes an argument whose static type does not match the def’s declared parameter type.

Spec: dsl §8.1

A @name(args) call supplies a different number of arguments than the def declares parameters.

Spec: dsl §8.1

A @ref produces a type incompatible with the CEL slot, component-arg, or {{…}} interpolation position it fills — including a non-renderable produced type or a :number format hint on a non-number.

Spec: dsl §8, dsl §7.6, dsl 0.24.0 §4

A fact atom (a seed facts: entry, a rule body/head atom, an ::assert/::retract, or a CEL fact query) supplies a different number of arguments than the relation declares.

Spec: dsl 0.3.0 §4, dsl 0.3.0 §5

A relation declares changedOn: while not reserved: true, changedOn: names an occasion no schema declares, or an excludes: entry names a relation of incompatible argument kinds or fails its symmetry contract.

Spec: dsl 0.25.0 §1, dsl 0.25.0 §6

A relation declares a field the schema does not recognize, an unknown tier, an out-of-range/duplicate key: index, or an argument domain that names no declared entity kind, enum, or domain.

Spec: dsl 0.3.0 §4

A relation name is declared more than once in a relations: block.

Spec: dsl 0.3.0 §4

A relation declares no args:.

Spec: dsl 0.3.0 §4

A relation is declared both derive: true and reserved: true, giving it two conflicting write owners.

Spec: dsl 0.3.0 §4, dsl 0.3.0 §5

A fact atom (a seed, rule, ::assert/::retract, or CEL fact query) names a relation no schema declares.

Spec: dsl 0.3.0 §4

A directive uses a removed attribute with no lossless rewrite (::music{track}, ::sfx{name}); the message names the replacement, and the migration is by hand.

Spec: dsl 0.37.0 §3.3, dsl 0.37.0 §4

lute.project.yaml still writes the removed sequence: key. It is never read and has no replacement key; every chain is declared in chapters:.

Spec: dsl 0.37.0 §2.2

A document uses the removed <scene> tag. A document’s sections are ## headings, and its scene is the document itself.

Spec: dsl 0.37.0 §2.2

A rename entry is malformed, has an unknown kind/key, duplicates a source or destination, or is not a canonical key mapping.

Spec: dsl 0.36.0 §3

Rename entries form a chain, self-loop, or cycle.

Spec: dsl 0.36.0 §3

A ledger source key is still present, or its destination key is absent after project resolution.

Spec: dsl 0.36.0 §3

A directive or content line uses an attribute’s old spelling (::music{action}, ::video{action}, ::cg{action}, ::label{id}, a content line’s id=); the message names the new spelling, and lute fix rewrites it.

Spec: dsl 0.37.0 §2.2, dsl 0.37.0 §4

A directive uses its old tag (::auto, ::cut, ::next, ::mark); the message names the new tag (::actor, ::cg, ::jump, ::label), and lute fix rewrites it.

Spec: dsl 0.37.0 §2.2, dsl 0.37.0 §4

A <choice> or <match> uses an attribute’s old spelling (label=, on=); the message names text= or subject=, and lute fix rewrites it.

Spec: dsl 0.37.0 §3.5, dsl 0.37.0 §4

A declared name is one the language keeps for itself — a state root naming an entity member, def or season, unset/true/false/null/_ naming a member, none or a CEL literal naming an id, a CEL keyword in a state path or id that becomes one, a CEL call or rule word naming a relation, narrator in cast:, or a number in a member list — so the name would be read as that word where it is used. The message names a replacement; lute --explain E-RESERVED-NAME lists every reserved name.

Every reserved name, where it is refused and what to write instead: Reserved names.

Spec: dsl 0.28.0 §1

A relation argument is _ in a context other than a ::retract pattern, which alone may contain wildcards.

Spec: dsl 0.3.0 §5

A <reward> element is malformed: an empty/missing kind, an amount= that is not a signed integer or a valid N..M range, an outcome= used on an objective-level reward or with a value other than "failed", a target= that is not a quoted id (an @ref or a bare target, which the IR cannot carry), or an attribute its reward kind declares written as an @ref (a reward’s attributes are static data the engine grants against: write a quoted value).

Spec: dsl 0.16.0 §2, dsl 0.16.0 §6, dsl 0.49.0 §3.3, dsl 0.52.0 §7.2

Two <reward>s of one quest (its own and its objectives’) carry the same id=; a reward id is unique within its quest.

Spec: dsl 0.37.0 §3.5

A <reward kind=…> value names no reward kind declared in the resolved capability snapshot’s rewardKinds vocabulary.

Spec: dsl 0.16.0 §4, dsl 0.16.0 §6

A <reward>’s target= violates its reward kind’s target contract: required but missing, present although the kind declares target: { forbidden: true }, or naming neither a declared entity-kind member nor a provider catalog id.

Spec: dsl 0.26.0 §2.5, dsl 0.49.0 §3.3

A rule’s count(...)/countDistinct(...) aggregate reads a relation that depends on the rule’s own head, but an aggregate may only read a relation outside its head’s own cycle.

Spec: dsl §9

A rule derives its head relation only where a positive body relation holds on the same arguments, but the two relations are declared mutually exclusive, so every derivation would violate that exclusion.

Spec: dsl 0.25.0 §1

A rule’s cel("...") guard cannot expand its @def/@def(args) references — the def is undeclared, its arity is wrong, or it is otherwise not usable in a guard.

lute run received an execution IR whose commands write an engine-owned state path or assert/retract a reserved relation.

Spec: dsl 0.32.0 §5

A runtime bridge result omits a field read by the pending bridge call or gives that field a value of the wrong type.

Spec: dsl 0.38.0 §5.3

A runtime input is not accepted while another input is suspended, or an answer is supplied without a matching await.

Spec: dsl 0.38.0 §5.3

A runtime condition query (evaluate of an IR expression or def of a project def) evaluates to an error, such as division by zero or int() of a non-number.

Spec: dsl 0.41.0 §5.1

An input was supplied after the runtime state entered a halted lineage.

Spec: dsl 0.38.0 §5.3

A runtime seed or input names an unknown project item or contains a value that cannot resolve to its declared type.

Spec: dsl 0.38.0 §5.3

A runtime bundle declares an execution IR major or minor version the runtime does not support.

Spec: dsl 0.38.0 §4.1

A runtime choice names an option absent from the pending menu or an option whose verdict is not open.

Spec: dsl 0.38.0 §5.3

A runtime choice or bridge result carries a request id different from the pending await.

Spec: dsl 0.38.0 §5.3

A runtime snapshot belongs to a different project bundle.

Spec: dsl 0.38.0 §7.2

A runtime snapshot major or minor version is incompatible.

Spec: dsl 0.38.0 §7.2

A timeout input was supplied while the pending await is not a timed choice.

Spec: dsl 0.40.0 §4.3

A seasons: declaration is malformed (an entry that is not a map, a missing or empty live, an unknown key, a bad season name), two schemas declare one season differently, or a season.<name>.* path, once: season:<name> or tier="season:<name>" names an undeclared season, or a scene’s legacy season: key (the episode number) holds a declared season’s name; a write to prev.season.* is E-QUEST-RESERVED-WRITE instead.

Spec: dsl 0.27.0 §5

Two sections of one document carry the same {#id}; a section id is unique within its document.

Spec: dsl 0.37.0 §3.1

A section heading has a malformed trailing {#id} identity suffix.

Spec: dsl §3.1

An execution artifact or engine matrix names an unknown semantic id.

Spec: dsl 0.33.0 §4

An ::set’s compound operator (+=/-=/*=) targets a path whose declared type is not number.

Spec: dsl §7.3.4

An ::set is malformed: it has no valid assignment operator (=/+=/-=/*=) after the path, uses == where = was meant, or indexes a state-family path with a param instead of a concrete key.

Spec: dsl 0.27.0 §2

An ::set’s right-hand expression’s decidable type does not match the type declared for the path it writes.

Spec: dsl 0.10.0 §3

A state: declaration gives a path a collection type (list/record/map), but author state must be scalar.

Spec: dsl 0.3.0 §3

A state: declaration is malformed: a non-string key, an unknown or incomplete type: (including an enum not nested under type:), a type: text (the type of a plugin directive attribute only), a bad default:/per: shape, or state: itself is not a map.

Spec: dsl 0.8.0 §4, dsl 0.51.0 §5.1

Two state: declarations of the same path disagree on type, default, per, or owner, and neither refines the other via extends:.

Spec: dsl §2

A read of a state path is not guaranteed set by any declared after: route reaching this node (error grade), or is set on only some of those routes (warning grade).

Spec: dsl §4.3

A state: path does not begin with one of the recognized namespace roots scene., run., user., app., or season..

A scene’s inline state: declares or overrides a state path that an imported (uses:) schema already declares, which a scene must never redeclare.

Spec: dsl §9.2

A state: shape refers to itself, directly or through another shape, forming a cycle.

A streaming continuation ends mid-construct at the end of input, or its body carries frontmatter or a heading, which a continuation body cannot contain.

A streaming continuation is submitted after the continuation compiler has already closed.

Appended source in a streaming continuation would change commands or state that were already emitted for an earlier prefix of the input.

A streaming continuation’s template is not a scene with at least one section.

A quoted attribute value uses a backslash escape other than the four defined ones (\", \\, \n, \t), or \{{ (a literal {{) in a value that does not take the label grammar — only a <choice text>, a prompt and a plugin text attribute do.

Spec: dsl §4.4, dsl 0.52.0 §3.2

A quest that an <objective quest=…> names as a subquest declares rearm=; a subquest activates with its parent, so once the parent has ended a rearmed child stays unset.

Spec: dsl 0.27.0 §5, dsl 0.28.0 §5

A block’s body, and often its close, is written on the opener’s own line; the opener, each body line and the </tag> close each need a line of their own.

Spec: dsl §2.3

A <tag …> opener’s attributes wrap past its own physical line instead of staying on one line as the grammar requires.

Spec: dsl §2.3

An edit-task suite trap did not refuse or flag the patch as expected.

Spec: dsl 0.36.0 §6, dsl 0.36.0 §8

A beat template is misused: <beat use=> names no component or one without a beat: header, a template beat: header is malformed or gives a header param a value it cannot take, a component declares a param named like a key of its use (component, when, at, or instance, or for a beat template a <beat> header key such as title, once or id) that no use could ever pass, or ::body appears outside a template’s top level.

Spec: dsl 0.27.0 §6, dsl 0.28.0 §1, dsl 0.46.0 §2.1

A narrative-time value (now() etc.) is used somewhere other than an ordering comparison against another narrative-time value or validAt’s second argument — as a bare value, in arithmetic, indexing, field access, a list literal, or with !=.

Spec: dsl 0.3.0 §6

A *.test.yaml’s file: names a document that does not exist.

A *.test.yaml has an unrecognized top-level or expect:-level key, or a key that is not a string.

A test’s file: names a lore document, which is looked up rather than played, so the test must instead name what to present (entry:/entries:, beat:) or judge it with expect:.

Spec: dsl 0.22.0 §5

A *.test.yaml’s transcriptContains/transcriptLacks needle names a speaker outside the project’s cast, an attribute no transcript line shows, or a value outside its domain, so it could never match a presented line.

A *.test.yaml declares no recognized expect: key, so the test asserts nothing and cannot pass.

An inline text modifier uses a backslash escape that is not one of the defined punctuation escapes.

Spec: dsl §3.6

An inline text modifier has malformed nesting or an unterminated span or attribute body.

Spec: dsl §3.6

An authored time value (a clip at, duration, delay, or <timeline duration>) carries more fractional precision than a millisecond.

Spec: dsl 0.10.0 §10.1

A <timeline> or <track> body contains non-staging content instead of only clip/staging elements.

Spec: dsl §7.4

A <timeline duration> is explicitly set below the maximum resolved end of its clips, which would truncate the timeline’s own content.

Spec: dsl §11.4

A --accepted-quest/accept: entry names an unknown quest id, a quest that carries a start predicate (which activates declaratively, needing no accept), or a quest referenced by a parent’s <objective quest=…> (a no-start child that activates via its parent).

Spec: dsl 0.4.0 §4.3, dsl 0.4.0 §4.4

lute trace --beat <id> targets a document that is not kind: lore, or names an id no <beat> in the document declares.

Spec: dsl 0.23.0 §4

A --choice entry names an unknown branch/hub id or an unknown choice id for that branch/hub, either before the walk starts or because the choice’s guard decides false when reached.

Spec: dsl 0.4.0 §4.3, dsl 0.4.0 §4.4

lute trace --entry <id> targets a document that is not kind: lore, or names an id no <entry> in the document declares.

Spec: dsl 0.19.0 §8

A --event/events: entry names a built-in lifecycle event (questActive, questComplete, questFailed), which is engine-derived and can never be user-fired.

Spec: dsl 0.4.0 §4.3, dsl 0.4.0 §4.4

A --fact/facts: entry, or a test’s expect.facts/expect.notFacts atom, does not parse as a ground fact pattern, or names an unknown relation, wrong arity, or a foreign argument.

Spec: dsl 0.4.0 §4.3

A --mock/mocks/*.yaml file is malformed — invalid YAML, not a mapping, an unrecognized top-level key, or a state:/facts:/choose:/events:/quests: section with the wrong shape.

Spec: dsl 0.4.0 §4.3, dsl 0.10.0 §8

A mock or test seed’s literal (--state <path>=<literal>, state:, quests:) or a test’s expect.state value is not compatible with the path’s reserved domain or declared type — for a { domain: K }, { entity: K } or enum path, not one of its members — or an answered bridge result lacks a field that content reads.

Spec: dsl 0.4.0 §4.3, dsl 0.24.0 §5, dsl 0.27.0 §2

A --state <path>=… seed names a path the clock derives (not seedable), a path not declared in the resolved schema, a path nothing in the document reads, or a bridge answer naming a call/field no directive reads or writes.

Spec: dsl 0.4.0 §4.3, dsl 0.24.0 §1, dsl 0.24.0 §5

A <track> declares neither subject, channel, nor a subject+property pair, so it has no identifying key.

Spec: dsl §7.4

A declaration is typed number, which is no longer a numeric type — a state row, a def or its parameter, a component parameter, a directive attribute, a bridge result, an occasion payload or a plugin state-shape field must choose int or double.

Spec: dsl 0.41.0 §3.2

A body line is no Lute construct — not a content line, directive, ::set or known block — or a block stands where it cannot, such as a <quest> inside a section.

Spec: dsl 0.5.0 §2.1

A block is never closed — its body reaches the end of the file, a ## heading, or the close of an enclosing block before its own </tag> — or a </tag> closes no open block.

Spec: dsl §5, dsl §7.3

A CEL slot, ::set target, or rule guard reads or writes a state path that no schema declares.

Spec: dsl §7.3.4, dsl §9.4

A @name interpolation or guard reference names a def that no schema declares.

Spec: dsl §8.1

A content line, directive or logic element carries an attribute key that the content-line grammar, the directive’s own declaration or the element’s fixed attribute table does not recognize, or a timing key (wait/duration/delay) or plugin stamp on a directive with no stamp carrier (::jump, ::label, ::clear), which would drop it. A plugin stamp scoped with on: to other surfaces is named with the surfaces it applies to; on <branch>, <hub> and <choice> the message also lists the stamps scoped to that element, and on a <reward> the attributes its reward kind declares (which it admits). code= on a directive without a text attribute names why: code is the localization identity of a directive with one.

Spec: dsl 0.1.0 §7.1, dsl 0.49.0 §4.1, dsl 0.50.0 §3.4, dsl 0.51.0 §5.2, dsl 0.52.0 §7.2

A ::directive names a tag no core or active plugin declares.

An <on event="…"> names an event that resolves to neither a built-in lifecycle event nor a capability-declared world event.

Spec: dsl 0.2.0 §4.5

An attribute or plugin frontmatter key referencing a providerRef id names an id absent from the pinned provider catalog.

Spec: dsl 0.49.0 §4.3

A document’s kind: frontmatter key has a value other than scene, quest, or lore.

Spec: dsl 0.2.0 §3.1, dsl 0.19.0 §2

A CEL guard slot compares a maybe-unset finite-domain subject to the foreign string literal 'unset', the most common misspelling of the DSL’s actual unset sentinel.

Spec: dsl 0.5.2 §2

A <match> subject that may be unset (a run./user./app. path with no schema default; a scene.* path, including a branch’s scene.choices.* record, is judged per path as E-MAYBE-UNSET) is not covered by an unset-matching arm or an <otherwise>.

Spec: dsl §11.2

A document’s uses:/extends: imports form a directed cycle.

Two peer imports at the same import depth declare the same def name differently.

Two peer imports at the same import depth declare the same relation or enum name differently.

Two peer imports at the same import depth declare the same state path differently.

A uses:/extends: import names a path that cannot be resolved or read.

A uses:/extends: import’s target document has parse or frontmatter errors of its own.

validAt is used over a derived relation, whose rule closure carries a CEL guard and so keeps no single well-defined timestamp.

Spec: dsl §8

A <when is="…"> literal falls outside the subject’s decided finite domain — a foreign enum member (a typo), a number/bool literal against a mismatched domain, or unset on a subject that is never unset.

Spec: dsl 0.4.0 §5.2, dsl §6.3

A <when> arm carries neither an is literal pattern nor a test guard, but one of the two is required.

Spec: dsl §7.3.1

A <when is="…"> alternative contains .. but is a malformed or empty range literal (for example .., a..b, 1...2, or 3..1).

Spec: dsl 0.18.0 §2

A <when is="unset"> arm needs its <match> subject to be a plain state path, and this subject is an expression.

Spec: dsl §7.3.1

Two <clip>s on different <track>s of a <timeline> write overlapping state targets at overlapping times.

Spec: dsl §11.4

An asset id looks like a placeholder that should be resolved before release.

A scene beat’s once defaults to run, but its when reads only user-tier state, so it may replay on every run unless once is authored explicitly.

Spec: dsl 0.22.0 §13, dsl 0.23.1

Two or more beats on one select: first occasion share the same priority and can be eligible at the same time, so which one wins falls to file order.

Spec: dsl 0.27.0 §11, dsl 0.22.0 §13

A select: first beat can never win its occasion because an earlier-ordered, always-eligible, never-spent beat with the same or absent target always wins first.

Spec: dsl 0.21.0 §5

A beat’s spentBy already holds at the start of play (every state path at its default, only the seed facts, each quest unset until its start holds — a start="true" quest is already active) — often spentBy read as “repeat while”, or an inverted !holds(…) copied from an old when — so the beat is spent before it can play: a spentBy beat stays spent once its condition has held. The message names the rewrite: when: "!(…)" (with once: false to repeat) for a beat that plays while the condition does not hold.

Spec: dsl 0.27.0 §5, dsl 0.28.0 §6

A beat answers an occasion the clock’s raise: map raises, and its when can hold only where the clock does not raise it — a dayEnd beat for a slot other than the day’s last, a dayStart beat for a later slot of the day the run starts — or only at the last dayEnd, which the advance that ends the clock raises after clock.ended turns true, when a terminal: that holds with clock.ended has already ended the game. So it never plays. Answer an occasion raised where it holds, or change its when; for the last dayEnd, raise it before the clock ends or write terminal: so it holds only once the beat has played. A beat whose when holds where the run starts — the slot occasion or dayStart there, which the clock does not raise because no advance: stops there — is warned too, but it plays if the engine raises the occasion when a run starts: then declare raiseAtStart: true on the clock, which silences it; otherwise answer an occasion raised where it holds. A beat some declared raise reaches (a directive’s or reward kind’s effects.raises of its occasion, for its target or for any when it declares no target:) may be raised at any position, so it is not reported.

Spec: dsl 0.28.0, dsl 0.51.0 §4.4

A declared or used project staging value, cast member, asset, or flow reference has no player binding.

Spec: dsl 0.40.0 §5

A player binding key is not used by any compiled project document.

Spec: dsl 0.40.0 §5

The player bindings’ bindingsVersion is not the toolchain line (the toolchain version’s MAJOR.MINOR): older — update it to the line (lute fix does it); newer — upgrade the toolchain, do not downgrade the stamp; not MAJOR.MINOR — restamp it.

Spec: dsl 0.47.0 §4.2

Two documents of one project each declare a <branch> or <hub> with the same id, and a play or test script under the root names that id as a choose: key. Ids need only be unique within a document, but choose: names a menu by its id alone, so the key answers both menus (and a list of decisions is consumed across both). An id no script names is not warned.

Spec: dsl 0.28.0 §7, dsl 0.49.0 §7.2

A content line’s speaker has a cast entry declaring a present: condition, but the line’s enclosing guards do not imply that condition holds.

Spec: dsl 0.24.0 §4

A providerRef id is not found in the pinned provider catalog, which may mean the snapshot is stale or offline rather than the id being wrong.

Spec: dsl §7.2

On a select: sequence occasion, where a chain of the project’s chapters: is the order within one raise, a listed scene writes its own priority:, which places it out of the order the chain lists. Remove the scene’s priority:, or move it in the chain’s scenes:.

Spec: dsl 0.28.0 §4

A scene listed in a chain of the project’s chapters: has its own when: that can stay false for good — it reads state the story may never set, or a window of the clock that closes: a when no raise of the chain’s occasion meets (a dayStart chain whose scene needs the day the run starts, unless the clock declares raiseAtStart: true because the engine raises it there), or one that no later raise meets once the scene before it has played late (a slot of the last day of a clock that ends) — and the next listed scene’s after: (the one the chain writes, or one it wrote itself) waits on it, so the chapters can stop there. A clock condition that a later raise still meets only delays the chain, and a condition over other owner: engine state is the engine’s to make true; neither is reported. Only a chain stalls: a hand-written after: on a scene outside chapters: is itself the statement “wait for that scene” and never warns. If the scene may be skipped, let the next one follow the scene before it (after: visited("<previous>"); the skipped one still plays first while eligible, as it ranks higher); if it must play, make sure the story makes its condition true, or let its when hold at a later raise. A scene some declared raise reaches (effects.raises) may be raised at any position: a when that only the clock’s schedule never meets is not reported, but one that has already expired by every position after the scene before it still is.

Spec: dsl 0.28.0 §4, dsl 0.29.0 §3, dsl 0.51.0 §4.4

Content follows an ::end directive in the same straight-line body, but the walk already terminated there so nothing after it can run.

Spec: dsl 0.8.0

Content follows an unguarded ::jump directive without max in the same straight-line body, but the jump leaves that body so nothing after it can run. A bounded ::jump{to max} does not end the body: once its takes are used up, control falls through to what follows.

Spec: dsl 0.12.0, dsl 0.51.0 §3.4

With identity.requireStable, a ::use has no explicit instance and is using the positional fallback; run lute tag to write one.

Spec: dsl 0.36.0 §2.2

A standalone component check has no caller in scope — either no project was resolved, or the resolved project has no document that ::uses the component — so the verdict covers only the component’s own frontmatter and body.

Spec: dsl 0.10.0 §9

An on= objective’s by= deadline (with no until=) provably implies before its done predicate can ever be judged, so the deadline fails the objective before it can complete.

Spec: dsl 0.24.0 §2.1

An objective’s done can only hold at clock positions where its by= deadline already holds — typically a visited beat whose when opens after the deadline — so the deadline fails the objective before it can be done.

Spec: dsl 0.28.0

An objective’s by= deadline can never hold — typically a moment past the end of a clock that ends — so it never fails the objective.

Spec: dsl 0.24.0 §2.1

A declared @def is never referenced by an @name use anywhere in the project’s content, other defs, or rule guards, and is not declared host: true.

Spec: dsl 0.24.0

A use of a declaration that is invalid (or of a plugin that failed to load) is not checked until that declaration is fixed; one note per invalid declaration, at its first dependant, counts the rest.

Spec: dsl 0.41.0 §3.2

A relation declared derive: true has no rules that produce it, so it is legal but permanently empty — almost always a typo’d rule head.

Spec: dsl 0.3.0 §7.1

Two different speakers show the same dialogue display name (from a cast entry’s name: or a component ::use{name=}), so the player cannot tell them apart.

Spec: dsl 0.26.0 §2.8

A declared domain is not read by any active construct — no directive attribute, content-line slot, plugin frontmatter key, state path, relations: argument, per:/subsetOf: family, or rule/condition query names it — so it enforces nothing.

Spec: dsl 0.10.0 §11.1, dsl 0.53.0 §6.2

An entry.<id>.read reference names an entry id no lore document in the project declares.

Spec: dsl 0.19.0 §5

An entry that can be read again in a run (a lookup entry, an entry beat without once, a once shorter than the run, a spentBy entry, a for= entry without once: run|user) writes state, but an entry’s writes apply on its first read in a run only; the message names the remedy for its shape (a <beat> with the same attributes, once="run", or a when="!entry.<id>.read" guard, which also silences it).

Spec: dsl 0.26.0 §8, dsl 0.19.0 §6

A content line’s action names a declared exit member of the action domain, but on a content line it has no staging effect — the character stays on stage.

Spec: dsl 0.10.0 §11.2

A guard’s relational query (holds/count) is guaranteed true on every route that reaches it, making the condition redundant.

Spec: dsl 0.20.0 §5

A <choice> arm both ::sets a path and records the same path via into=, recording it twice.

Spec: dsl 0.6.0 §2.2

A compiled line record is missing text for a locale its localization bundle declares.

Spec: dsl 0.8.0 §7

A merged translation was made from a different source text than the record’s current one — the line, option label or prompt changed after the lute loc export the translator worked from (its stored sourceHash differs). The translation is still merged; re-export and update it.

Spec: dsl 0.47.0 §3.2

With identity.requireStable, a content line (or a call of a directive with text attributes) has no explicit code and compiler allocation is being used; run lute tag to write one.

Spec: dsl 0.36.0 §2.2, dsl 0.51.0 §5.3

A document’s luteVersion frontmatter stamp is present but differs from the toolchain’s current DSL version, suggesting it was copied from an older example.

Spec: dsl 0.6.1 §3

A frontmatter document authors a legacy scene-identity key (such as character, season, or episode) alongside id:, but id: now carries scene identity so the legacy key should be removed.

Spec: dsl 0.15.0 §4

A required (!optional) objective’s visibleWhen visibility gate provably never holds, so it can never be visible or tracked even though it still gates quest completion.

Spec: dsl 0.4.0 §5.3

Within the declared clock windows of its own document’s beats, a required objective may be stranded because those windows can all close and it has no until=/by=; a quest that re-arms (run or season tier, rearm=) or an objective another document’s beat can complete is not reported. No path search is performed.

Spec: dsl 0.31.0 §3, dsl 0.41.0 §3.4

A scene, entry or bundle beat answers an occasion declared raisedBy: declared — the host raises it only through a directive’s or reward kind’s effects.raises — but no declared raise in the project reaches it (none raises the occasion for its target:, for occasion.target, or, when it declares no target:, for any target), so it never plays. Add a raises entry to the directive or reward kind that leads there, or drop raisedBy: declared if the host raises the occasion on its own. An occasion the project clock’s raise: map raises is raised outside any declared raise and is not reported; a lute play/lute test step that raises the occasion is no raise (a test proves a test, not the game). Whole-project check only.

Spec: dsl 0.51.0 §4.5

A <match>’s <otherwise> arm is provably unreachable because earlier unguarded is arms already cover the subject’s whole domain.

Spec: dsl 0.4.0 §5.2

Two <when> arms provably match the same value, so the later arm is unreachable under first-match-wins ordering.

Spec: dsl §11.2, dsl 0.18.0 §4

Info from a single-file check (and the LSP): the document reads quest.<id>.* for a quest it and its imports do not declare. Quest references are resolved only by whole-project lute check, so this check did not judge the read. Never raised by whole-project check, compile or wasm.

Spec: dsl 0.49.0 §7.1

A manifest does not govern under the forced --project root and would have resolved differently, so its settings are not applied to any document.

A quest’s <on event="questFailed"> handler never runs because the quest can never fail — no fail condition, no required objective with a by= deadline, no failing required subquest, and no parent quest that could cascade-fail it.

Spec: dsl 0.22.0 §7

An accept-driven quest is never named by any ::accept{quest=…} or reward kind effects.accepts and is not accept="external", so nothing in the project ever accepts it.

Spec: dsl 0.24.0 §2, dsl 0.25.0 §5, dsl 0.50.0 §5.4

A quest’s rearm= condition is constant ("true", "false", or a def or comparison that folds to one), so it never turns from false to true and the quest never rearms.

Spec: dsl 0.27.0 §5, dsl 0.28.0 §5

A reserved quest.<id>.state / quest.<id>.objectives.<oid>.done reference (or similar) names a quest id or objective id no quest document in the project defines.

Spec: dsl 0.5.1 §1.4

A has(quest.<id>.state) guard is always true, since a quest’s state is always assigned — unset until activation, then a real state — so the check tests nothing.

A quest with no tier= (so it defaults to user-tier, persisting across runs) reads only run-tier state in its conditions — run.*, clock.* over a run.* day, run-tier facts, or subquests that are run-tier or flagged too, but not visited(), which a new run keeps — suggesting it (and its quest tree) was meant to reset each run.

A stored (not derive: true) relation declares no tier:, so it is run-tier: its facts start over at every new run, from its facts: seed if any (an engine-owned reserved: true relation’s facts are forgotten). Write tier: run to keep that, or user, app or season:<name> for facts that outlive the run.

Spec: dsl 0.28.0 §5

A declared, non-reserved relation is written (asserted, seeded, or derived) but never read by any condition, rule body, or def — the facts it records change nothing.

Spec: dsl 0.24.0

A quest handler’s ::set writes the same path a <reward kind="…" credits=…> already credits when granted, so the reward pays twice.

Spec: dsl 0.23.0 §8

A beat with once: season:<name> (or a tier="season:<name>" quest with a start) whose when (or start) does not imply the season’s live condition: once only sets how long the beat stays spent, so it plays even while the season has never opened. Add the season’s live condition (or a def that reads it) to the when.

Spec: dsl 0.28.0 §7

Within the declared clock windows, two required objectives may contend for the same single clock position; no path search is performed.

Spec: dsl 0.31.0 §4

A beat’s spentBy can turn false again after it has held — it reads a fact some ::retract / ::assert or a directive’s declared effect can undo, a season’s state, facts or quest (reset each time the season opens), or a quest rearm returns to unset — but with no once written the beat stays spent for the rest of the run, unlike a condition judged afresh at each raise. The message names the rewrite: once: false with when: "!(…)" to judge it afresh, once: season:<name> for a season, or once: run to keep it spent on purpose (a written once silences the warning).

Spec: dsl 0.28.0 §6

A content line or ::actor targets a character who already left the stage (via a declared exit, a ::bg scene change, or ::clear) and was never re-shown, so the staging is impossible. A line’s message names both ways to show them again: an ::actor, or a plugin directive lowered to the actor record (lower: { record: actor, fields: { character: { fromAttr: character } } }), which stages like ::actor.

Spec: dsl 0.22.0 §12, dsl 0.50.0 §7

A beat template’s when: or spentBy: header reads a member as a path segment spelled with a param (user.bond.@who). It works in a header, but a component body refuses that spelling; write user.bond[@who], which both accept.

Spec: dsl 0.28.0 §3

A <beat use=…> writes its own when=, which replaces the template’s when: whole, so the template’s condition no longer gates the beat (and an argument only that condition read is unused). Write both conditions in the use’s when=, or give the template a param to conjoin (when: "<condition> && (@only)") and pass it instead.

Spec: dsl 0.28.0 §3

The schema’s terminal: reads state a new run keeps (visited(…), user.*, app.*, entry.<id>.everRead, a user-tier quest or relation), so once it holds no new run can play on. An ending that outlives runs on purpose (a roguelike’s permanent ending) says so with terminal: { when: "<condition>", persists: true }, which silences the warning.

Spec: dsl 0.28.0 §2, dsl 0.29.0 §5

A <choice> label is wholly wrapped in […], Ink’s bracket suppression. Lute shows a label exactly as written, so the brackets appear on the button; write the label without them. A leading tag followed by more text ([Persuasion] Step closer) is not warned.

Spec: dsl 0.28.0 §2

Line text or a choice label holds a // … comment or ends in an Ink #tag. Text after : is literal, so the player sees it; a comment is // … on a line of its own, and Lute has no line tags.

Spec: dsl 0.28.0 §2

Line text or a choice label holds Ink glue <>. Lute joins no lines and text after : is literal, so the player sees <>; write the whole sentence on one line.

Spec: dsl 0.28.0 §2

A content line’s whole text is exactly @<name> for a declared def or component param, which ships as the literal string "@<name>" instead of being resolved.

Spec: dsl §7.6

Line text or a choice label holds a single-brace group that reads as another language’s markup: a state path or def ({run.oil}), a Yarn {$var} or {0} placeholder, Ink conditional text ({cond: text}) or alternatives ({~a|b}). Single braces are always literal and a backslash does not escape them (\{run.oil\} ships its backslashes too), so braces meant to show are written as they are; interpolation is {{run.oil}}, and conditional text is a guarded line or a <match>.

Spec: dsl 0.28.0 §2

A <timeline> track has more than 12 clips, which the checker suggests splitting.

Spec: dsl §11.4

A <timeline> has more than 40 clips across all its tracks combined, which the checker suggests splitting.

Spec: dsl §11.4

A <timeline> has more than 8 tracks, which the checker suggests splitting.

Spec: dsl §11.4

A supplied --fact/mock-YAML fact’s relation is judged not producible by any authored producer, so a walk seeded with it proves nothing about reachable play.

Spec: dsl 0.6.1 §4

A <when test="…"> arm is written as a CEL literal comparison that the is= pattern form would say more clearly and that the checker can reason about directly.

Spec: dsl 0.18.0 §3, dsl §7.3.1

Under whole-project check --wip, a guard or objective is dead only because a relation it needs has no producer written yet (no seed, ::assert, rule, or reserved declaration, or only a component ::assert with an unbound @param); the message names the error code it is without --wip: E-ARM-DEAD, E-BEAT-UNREACHABLE, E-ENTRY-UNREACHABLE, or E-OBJECTIVE-UNSATISFIABLE.

Spec: dsl 0.23.0 §10, dsl 0.26.0 §2.6