Skip to content

Diagnostics

Every problem the compiler finds is reported as a diagnostic: a severity, a stable code, a message, and the line and column it came from. This page is the catalogue of those codes.

A message is written for a person and gets reworded whenever a clearer wording is found. A code never changes. So a code is what you match on, suppress on, and group by - anything reading the message text breaks the next time the message is improved.

The CLI prints a diagnostic in the format editors and build servers already parse - the file, the position, the severity, the code, and the message - followed by the offending line and a caret:

nested/broken.play(3,5): error PLAY0028: Unknown slice type 'Wat' - expected StateChange, StateView, Automation or Translate
3 | slice Wat DoIt
| ^

There are three severities. Error means the document does not compile. Warning means the document compiles but something is very likely wrong - almost always a name nothing declares. Information means something worth knowing that changes nothing.

The prefix is PLAY, after the .play documents this compiler reads.

Cratis Arc has its own catalogue, the SP codes, for generating a .play document from C# source. The two run one after the other - Arc generates a document and hands it straight to this compiler to read back - so both sets of diagnostics land in the same build log. A shared prefix would make SP0034 and a compiler code of the same number indistinguishable at a glance and identical to a SP\d{4} filter, which is why the prefixes deliberately have nothing in common. Arc’s codes describe what the generator could not express; the codes here describe what the compiler could not read.

A code is an identifier, not a position in a list.

  • A number is never reused. When a diagnostic is retired, its number is retired with it and left behind as a gap in the sequence. Handing that number to something else would silently change what an existing suppression means.
  • A number is never renumbered. Inserting a code in the middle of the catalogue would change the meaning of every code after it.
  • A new code is appended at the end of the sequence whatever it is about, so the number says when a code was added rather than where it belongs. Use this page, not the numbering, to find the codes for an area.
  • A code outlives its message. Two constructs hitting the same condition share one code - a property line the parser cannot read reports PLAY0016 whether it sits in a type or in an event.

Diagnostic carries the code alongside the severity, the message and the location, so a consumer filters on it directly:

using Cratis.Screenplay;
using Cratis.Screenplay.Diagnostics;
var result = new ScreenplayCompiler().Compile(source);
// A document assembled a piece at a time refers to events the pieces have not introduced yet,
// so that one warning is expected here and everything else is not.
var unexpected = result.Diagnostics
.Where(diagnostic => diagnostic.Code != DiagnosticCodes.UnknownEvent)
.ToList();

DiagnosticCodes declares every code in this catalogue as a named constant, so the compiler catches a typo that a string literal would not.

The language service behind the VS Code extension and the Monaco editor checks a subset of what the compiler checks, and it reports the compiler’s code for every condition in that subset. So the Unknown type 'Foo' you get as a squiggle and the one the CLI prints are the same PLAY0165, and can be looked up here, filtered on, and matched against a build log:

import { diagnosticCodes, validateLines } from '@cratis/screenplay-language';
const unknownTypes = validateLines(lines).filter((issue) => issue.code === diagnosticCodes.unknownType);

diagnosticCodes names the codes the editor reports, the same way DiagnosticCodes names them for the compiler. A ValidationIssue carries the code as code, and it reaches the editor: a Monaco marker gets it as code, a VS Code diagnostic as Diagnostic.code.

A few editor checks carry no code, deliberately. The capture and projection validators enforce structural rules that no compiler run reports - a capture must include a source block, an append block must include a when clause - and there is no PLAY number for something the compiler never emits. Minting one would make this catalogue describe two different tools, which is the thing the PLAY prefix was chosen to avoid. Those conditions are reported without a code until the compiler checks them too.

CodeSeverityReported when
PLAY0001ErrorA line at the top level of a document opens with a word nothing at that level is declared by.
PLAY0002ErrorA domain line is not domain <Qualified.Name>.
PLAY0003ErrorA document declares a domain more than once, and a document has at most one.
PLAY0004Errordomain is declared after another construct, and it names what the whole document is about.
PLAY0005ErrorAn import line is not import <Qualified.Name> [from "<origin>"], or its origin metadata is invalid.
PLAY0006WarningA line is indented with tabs, and Screenplay decides nesting from spaces.

Event-source declarations and command stream routes are admitted by ESM v8. Property-path mappings and handler commands remain refused with PLAY0268. Binding reports PLAY0273 for generated mappings, stored-name collisions (including pin-versus-name), the reserved stored source name Default, the reserved stored stream name All (including id "All"), or a routed fixture whose source identifier type cannot be resolved. Reserved-name checks are binding-only; authoring validation still accepts the declarations. For All, rename the stream without retaining that stored-name pin. A stream reference selects a classification, never the identity destination supplied by for. Handler commands may author routes without declaring their returned events.

CodeSeverityReported when
PLAY0503ErrorAn event source or its source-owned stream has invalid syntax, a repeated directive or physical declaration, an invalid rename pin, or an optional, collection or known composite identifier type. Composite stream-id blocks also refuse fewer than two parts, duplicate names, modifiers, children, empty/repeated headers and mixed scalar/block forms. Duplicate physical sources make their child ownership ambiguous.
PLAY0504ErrorA known source’s stream does not resolve uniquely, or a command route or stream-id mapping is invalid, missing or incompatible, including missing, unknown, duplicated or mismatched-shape composite parts. Scalar literals and composite literal parts refuse empty, non-NFC or ill-formed text and integers outside ±9007199254740991 in Double numeric mode. A command identifier or known production destination type differing from the source’s nominal identifier type is refused, never silently retargeted.
PLAY0505ErrorAn exact stream Source.Stream header resolves both to one source-owned stream and to a viable imported value type. Both candidates remain visible; neither is selected automatically.
PLAY0506ErrorA known scalar stream-id or composite part type falls outside text and UUID values and their nominal concepts, plus integer-backed concepts. Bare Int is rejected. Other types need a future portable formatting contract. Unavailable imported shapes remain unresolved.
PLAY0507InformationA source or stream’s rename-only id pin repeats its current name. New declarations omit the pin.
PLAY0547ErrorA specification routing directive or composite part block is malformed, empty, repeated, conflicting, has invalid children, or leaves effective no stream on a given or when append event. Event examples and redelivery locators may carry no stream.
PLAY0548ErrorA when <Command> occurrence declares stream or no stream; the route belongs to the command declaration.
PLAY0549ErrorA specification stream reference is missing or ambiguous, its key mapping is missing or superfluous, or the scalar stream id or composite part is nonliteral or incompatible, or contains empty, non-NFC or ill-formed text or an integer outside ±9007199254740991 in Double numeric mode. Composite routes require every declared part exactly once and refuse unknown/duplicate names and mismatched scalar/block forms.
PLAY0550ErrorA routed given or when append lacks for, a routed identity is not a compatible concrete literal, or a source without identifier has no unambiguous known producer destination type.
PLAY0551ErrorA then route or destination type contradicts the command under test, which is the event’s only producer in the whole model. Other producers defer the comparison.

Command headers are classified against the complete immutable compilation input, including resolved file imports. @stream Qualified.Type, stream String and modified property forms remain properties; production stream = value and stream String = value remain payload mappings. When neither a source nor a property type resolves, the header keeps its legacy property interpretation and unknown-type evidence, including deeper legacy command members. A misspelled source name cannot be distinguished from an unresolved qualified property by spelling alone. Stream-id children do not override this rule. Candidate discovery uses the same inline-language registry as the committed parse; registered code payloads cannot declare sources or property types.

Syntax JSON retains every ambiguous or duplicate header in CommandSyntax.streamCandidates, including its property interpretation when ambiguous. stream holds at most one unambiguous route. Deeper legacy properties remain command members, without duplicating the candidate property. Such invalid drafts cannot be printed or expanded into .play files: export throws InvalidSyntaxJson rather than selecting an interpretation or dropping a header. Retain syntax JSON until you repair the draft. Use @stream for an intended qualified property, or remove the competing type interpretation for an intended route; remove duplicate route headers before export.

CodeSeverityReported when
PLAY0007ErrorA concept line is not concept <Name> : <Type>.
PLAY0008ErrorA concept is declared over a primitive the language does not have.
PLAY0009ErrorA value of an enumeration concept is not an identifier.
PLAY0010ErrorA line in a concept body opens with a word a concept declares nothing by.
PLAY0011WarningA value of an enumeration is called validate, which the concept body reads as an empty validate block.
PLAY0012ErrorA concept gives a reason, scope or personal-data qualifier for a marker it does not carry.
PLAY0013ErrorA concept gives the reason for one attribute more than once.
PLAY0515ErrorA concept marked pii or secret is used as a command identifier, an explicit for destination, an event source identifier, a scalar stream id type, a composite stream id part type, or a command route mapping source (including nested property paths). The message names the attribute and position, never a value. A mapping using the same protected concept already reported at its resolved stream-id declaration is not reported again; a different protected source concept is still reported. Specification route literals rely on their declaration’s check. Use a surrogate Uuid identifier and keep personal data or operational secrets as properties. Reaction destinations also check values typed directly in the trigger clause, even for an undeclared or registered trigger. When a reaction source names both an event and a declared trigger, a protected destination in the resolved event shape or the trigger clause is rejected.
PLAY0653WarningA concept header repeats a compliance marker, including pii personal. Both compilers keep the first marker for each wire identity and attach body settings to it; canonical printing writes one marker. The concept-line repair removes later tokens with PreserveTrivia.
PLAY0565InformationLegacy @pii, sensitive or @sensitive spelling. Use bare pii/secret; per-line and document repairs preserve notes and trivia.
PLAY0566ErrorUnknown concept compliance marker; expected pii, personal or secret.
PLAY0567ErrorScope belongs to secret and must be subject, namespace or global.
PLAY0568ErrorA concept declares secret scope more than once.
PLAY0569WarningExplicit secret scope on pii secret is ignored because only Chronicle [PII] renders.
PLAY0570ErrorInvalid personal-data qualifier or unknown Art. 9(1) category.
PLAY0571ErrorA concept declares more than one pii special category.
PLAY0590ErrorAn event marks more than one data-subject property; each extra mark names the first. Choose one; no automatic repair is safe.
PLAY0591ErrorA subject must be a required scalar String, Uuid or their concepts, or an Int-backed concept. Optional values, collections, composites, bare Int, enums, Decimal, Bool, Date and DateTime are refused.
PLAY0592ErrorA subject concept is pii or secret; EventContext.Subject is plaintext. Use a surrogate identity.
PLAY0593ErrorThe subject modifier belongs only to event properties, not commands, types, operation inputs, trigger or reaction data or response fields (decision 0008).
PLAY0594ErrorRead model subjects are not yet supported; #559 covers the mark and Chronicle’s reserved _subject, __subject and __subjects names.
PLAY0595ErrorSubject is duplicated or out of modifier order. Write each modifier once: Type optional generated identifier subject.
CodeSeverityReported when
PLAY0596ErrorInvalid purpose declaration, reference or field syntax.
PLAY0597ErrorUnknown basis, condition or erasure-exception value.
PLAY0598ErrorA purpose repeats a singleton field.
PLAY0599ErrorA purpose name is declared more than once.
PLAY0600WarningA purpose reference does not resolve.
PLAY0601WarningInterest is declared without basis legitimateInterests, or that basis has no nonblank interest statement.
PLAY0602WarningOpt-in purposes check: a slice carries pii without a declared purpose in scope.
PLAY0603WarningOpt-in purposes check: special-category data lacks a purpose’s condition.
PLAY0604WarningOpt-in purposes check: criminal data lacks a purpose’s authorization.
PLAY0605WarningOpt-in purposes check: a purpose has no basis.
PLAY0606WarningOpt-in purposes check: a purpose is never referenced.

These are structural findings, not legal verdicts. See Processing purposes.

CodeSeverityReported when
PLAY0014ErrorA type line is not type <Name>.
PLAY0015ErrorA type declares no properties, and a type is the properties it holds.
PLAY0016ErrorA property line is not <name> <Type>.
PLAY0017ErrorA property outside a command is marked as the identifier, which only a command property can be.
CodeSeverityReported when
PLAY0018ErrorAn event line is not [public] event <Name> [generation <N>] [from "<origin>"], or its visibility/origin metadata is invalid.
PLAY0019ErrorA property of an event is marked as the identifier, and an event never carries its event source id.
PLAY0020WarningA property called tag is read by the event body as a static tag rather than as a property.
PLAY0446ErrorAn event generation is zero, exceeds the 32-bit generation range, or uses Chronicle’s reserved unspecified value (4294967295).
PLAY0447ErrorThe same event in one slice declares a generation twice; two unmarked declarations are both generation 1 and therefore duplicate.
PLAY0448ErrorAn event in one slice omits a generation between 1 and its latest generation.
CodeSeverityReported when
PLAY0021ErrorA module line is not module <Name>.
PLAY0022ErrorA line in a module body opens with a word a module declares nothing by.
PLAY0023ErrorA feature line is not feature <Name>.
PLAY0024ErrorA line in a feature body opens with a word a feature declares nothing by.
PLAY0025ErrorA slot declared by a layout, screen template or dialog template is not an identifier optionally followed by contributes.
PLAY0026ErrorA line in a layout, screen template or dialog template body opens a block none of them declares anything by.
PLAY0027ErrorA slice line is not slice <Type> <Name>, or direction is malformed, repeated or declared outside Translate. Legacy directionless translations remain accepted.
PLAY0028ErrorA slice is declared with a type the language does not have.
PLAY0029WarningA line in a slice body opens with a word a slice declares nothing by.
CodeSeverityReported when
PLAY0030ErrorA persona line is not persona <Name>.
PLAY0031ErrorA policy line in a persona body is not policy <Name>.
PLAY0032ErrorA line in a persona body opens with a word a persona declares nothing by.
CodeSeverityReported when
PLAY0033ErrorA command line is not command <Name>.
PLAY0034ErrorA line in a command body opens with a word a command declares nothing by.
PLAY0035ErrorA command declares both produces and handler, which say the same thing two ways.
PLAY0036ErrorA command marks more than one property as its identifier.
PLAY0037ErrorA concurrency line carries anything beyond the keyword.
PLAY0038ErrorA command declares more than one concurrency block, and a command has at most one.
PLAY0039ErrorA line in a concurrency block names a dimension the block does not have.
PLAY0040ErrorA dimension of a concurrency block is not written the way that dimension is written.
PLAY0041ErrorA concurrency block states one dimension more than once.
PLAY0042ErrorA produces line is neither produces <EventType> nor produces when <condition>.
PLAY0043ErrorA produces when condition is followed by no event to produce.
PLAY0044ErrorA mapping line is not <property> = <source>.
PLAY0045ErrorA handler names neither a file, an inline code block nor an explicit implementation wrapper.
PLAY0046ErrorA line in a handler body opens with a word a handler declares nothing by.
CodeSeverityReported when
PLAY0047ErrorA query line is not query <Name> => [observable] <ReadModel>.
PLAY0048ErrorA line in a query body opens with a word a query declares nothing by.
PLAY0049ErrorA by or filter parameter is not <keyword> <name> <Type> [from <source>].
PLAY0050ErrorA performer line carries anything beyond the keyword.
PLAY0051ErrorA query declares more than one performer, and a query has at most one.
PLAY0052ErrorA performer names neither a file nor an inline code block.
PLAY0053ErrorA line in a performer body opens with a word a performer declares nothing by.
CodeSeverityReported when
PLAY0054ErrorA projection document holds a top level line that does not open a projection.
PLAY0055ErrorA projection document declares no projection at all.
PLAY0056ErrorA projection line is not projection <Name> [=> <ReadModel>].
PLAY0057ErrorA projection declares no directives, so it builds nothing.
PLAY0058ErrorA line in a projection body opens with a word a projection declares nothing by.
PLAY0059ErrorA projection declares more than one key.
PLAY0060ErrorA from block declares more than one key.
PLAY0061ErrorA from line names no event to read from.
PLAY0062ErrorAn event reference is not a name the language can read as one.
PLAY0063ErrorA join line is not join <property> on <key>.
PLAY0064ErrorA join block holds a line that is not with <EventType>.
PLAY0065ErrorA children line is not children <collection> identified by <key>.
PLAY0066ErrorA nested line is not nested <property>.
PLAY0067ErrorA nested block reads from no event, so nothing ever fills it.
PLAY0068ErrorA remove line is neither remove with <EventType> nor remove via join on <EventType>.
PLAY0069ErrorA remove block holds a line other than parent.
PLAY0070ErrorA clear line is not clear with <EventType>.
PLAY0071Errorclear with is written where there is nothing to clear.
PLAY0072ErrorA part of a composite key is not <property> = <expression>.
PLAY0073ErrorA composite key part is a template expression, which a key cannot be.
PLAY0074ErrorA composite key declares no parts.
PLAY0075ErrorA mapping line in a projection is not one the language can read.
PLAY0452WarningMore than one automap or no automap appears in the same projection scope. The last setting wins; printing preserves the authored settings and their individual comments.
PLAY0514WarningA projection mapping, children, or nested target is absent from the declared read-model or element shape. Unknown or imported shapes are not guessed.
CodeSeverityReported when
PLAY0076ErrorA capture document holds a top level line that does not open a capture.
PLAY0077ErrorA capture document declares no capture at all.
PLAY0078ErrorA capture line is not capture <Name>.
PLAY0079ErrorA line in a capture body opens with a word a capture declares nothing by.
PLAY0080ErrorA map entry is not <property> = <source> [translate].
PLAY0081ErrorA translation is not "<source>" => <target>.
PLAY0082ErrorA split line is not split <property> by "<separator>".
PLAY0083ErrorA target of a split is not a property path.
PLAY0084ErrorAn append line is not append <EventType>.
PLAY0085ErrorA line in an append body opens with a word an append declares nothing by.
PLAY0086ErrorA when line names no trigger.
PLAY0087ErrorA when clause is not one of the shapes a trigger is written in.
PLAY0088ErrorA value transition is not when <Path> from <value> to <value>.
PLAY0089ErrorA when clause combines properties with both and and or.
PLAY0090ErrorA when combinator is followed by no property.
PLAY0091ErrorA line in a children or nested block is neither map nor append.
CodeSeverityReported when
PLAY0092ErrorA specification document holds a top level line that opens neither a specification nor an example.
PLAY0093ErrorA specification document declares no specification at all.
PLAY0094ErrorA specification line is not specification <Name>.
PLAY0095ErrorA line in a specification body opens with a word a specification declares nothing by.
PLAY0096ErrorA when line is not when <CommandType>.
PLAY0097ErrorA specification issues more than one command, and a specification is one example.
PLAY0098ErrorA then error line is neither then error nor then error "<reason>".
PLAY0099ErrorA given readmodel or then readmodel line does not name a read model type.
PLAY0100ErrorA given or then line does not name an event type.
PLAY0101ErrorA value a specification step states is not <property> = <value>.
PLAY0453ErrorA then no readmodel line lacks a view or key, uses exactly, or has child mappings.
PLAY0518ErrorAn example declaration is not example <Name> : <EventOrCommandOrReadModel>.
PLAY0519ErrorA fixture assigns the same property more than once, including across a step’s inline assignment and indented body. Assign it once; overriding a value from an example is a separate operation.
PLAY0520ErrorAn example’s type or reference is unknown, ambiguous, or not an event, command, or read model. Qualify the declaration; example inheritance is not supported.
PLAY0521ErrorAn example name collides with a type name or repeats in the same scope. Choose a distinct example name.
PLAY0522ErrorA step references an example of another kind. Use the corrected step spelling suggested by the diagnostic.
PLAY0523ErrorAn example supplies an undeclared current-generation property, an invalid generated fixture, or for on a read model. Use only the current type’s allowed fixture lines.
PLAY0524ErrorBinding an exact-shape specification step found a missing required property after expansion. The diagnostic names the step, property, and example when used. Supply the property in the example or step; no defaults are assumed.
PLAY0525ErrorSemantic admission found a stated example value incompatible with its type, or for without one unambiguous required scalar destination type. Fix the value or its destination contract, even if the example is unused or that value is overridden. Partial top-level examples remain allowed. Ordinary fixture diagnostics also apply to null, nonconcrete, structured and generated values.
PLAY0526ErrorA command or read-model example states a route. Only event examples carry routes; a command’s route comes from its declaration, and read models have none. Top-level streamId = value is payload, not route metadata.
CodeSeverityReported when
PLAY0102ErrorA screen line is not screen <Name>.
PLAY0103ErrorA line in a screen body opens with a word a screen declares nothing by.
PLAY0104ErrorA data line is not data <ReadModel> via query <Query> [by <param>].
PLAY0105ErrorAn action line is not action <Command>.
PLAY0106ErrorA line in an action body is neither label nor navigate to.
PLAY0107ErrorA navigation is not navigate to <Screen> [by <param>].
PLAY0108ErrorA line under a screen layout does not name a slot.
PLAY0109ErrorA title line is not title "<text>".
PLAY0110ErrorA line in a table body is neither column nor on row-click navigate to.
PLAY0111ErrorA line in a summary body is not field <property> label "<text>".
CodeSeverityReported when
PLAY0112ErrorA policy line is not policy <Name>.
PLAY0113ErrorA line in a policy body is neither require nor an inline code block.
PLAY0114ErrorA policy states nothing it requires of the caller.
PLAY0115ErrorA policy condition holds a token the language has no reading for.
PLAY0116ErrorA policy requirement states no condition.
PLAY0117ErrorA group opened in a policy condition is never closed.
PLAY0118ErrorA role requirement names no role.
PLAY0119ErrorA claim requirement names no claim.
PLAY0120ErrorA claim requirement does not say what the claim is matched against.
PLAY0121ErrorA claim match states nothing to match the claim to.
PLAY0122ErrorAn authorize clause names no policy.
PLAY0123ErrorA policy is referred to by something that is not a policy name.
PLAY0440ErrorA policy combines require with an inline code block or a file implementation. Choose one form.
PLAY0441ErrorA policy has more than one require line; combine the conditions with and/or in one require.
CodeSeverityReported when
PLAY0124ErrorAn authentication line carries anything beyond the keyword.
PLAY0125ErrorA document declares more than one authentication block, and a document has at most one.
PLAY0126ErrorA provider line is not provider <Name>.
PLAY0127ErrorA setting of a provider is not <name> <value>.
CodeSeverityReported when
PLAY0128ErrorA seed line carries anything beyond the keyword.
PLAY0129ErrorA seed group is not for "<event source id>".
PLAY0130ErrorA line in a seed group does not name an event type.
PLAY0131ErrorA value a seeded event carries is not <property> = <value>.
CodeSeverityReported when
PLAY0132ErrorA constraint line is not constraint <Name>.
PLAY0133ErrorA constraint states nothing it holds the application to.
PLAY0134ErrorA line in a constraint body is not one the language can read.
PLAY0135ErrorA constraint mixes unique event and unique property rules, combines a file rule with another rule, repeats a singular option, or repeats a target, release, or property. An event cannot both claim and release the same constraint. Several distinct unique rules of the same kind are allowed.
CodeSeverityReported when
PLAY0136ErrorA reaction line is not reaction <Name>.
PLAY0137ErrorA line in a reaction body is not a trigger the language reads.
PLAY0138ErrorA reaction states no trigger, so nothing ever sets it off.
PLAY0139ErrorA line in a reaction trigger body opens with a word a trigger declares nothing by.
CodeSeverityReported when
PLAY0140ErrorA validate line is neither validate nor the deprecated validate csharp form.
PLAY0141ErrorA validation rule is not one the language can read.
PLAY0142ErrorA validation rule names a rule the language does not have.
PLAY0143ErrorA rule line does not name the rule with an identifier.
PLAY0144ErrorA named rule names neither a file nor an inline code block.
CodeSeverityReported when
PLAY0145ErrorA description line is not description "<text>".
PLAY0146ErrorA fenced description holds no text.
PLAY0147ErrorSomething is described more than once, and a description is given once.
PLAY0148ErrorA tag line carries no value.
PLAY0149ErrorA tag value is neither an identifier, a string literal nor a context expression.
CodeSeverityReported when
PLAY0150ErrorA literal expression carries no value.
PLAY0151ErrorA $causedBy expression names a property the cause does not carry. The short form admits what the event context catalog lists below causedBy: subject, name, userName and onBehalfOf, which is itself an identity with the same members.
PLAY0152ErrorAn expression is not one the language can read.
PLAY0153WarningA $context path opens with a root the context does not have.
PLAY0154WarningA $context.causedBy path names a property the cause does not carry.
PLAY0155WarningA $identity or $context.identity path names a property the caller identity does not carry.
PLAY0156ErrorA template expression is never closed.
PLAY0157ErrorAn interpolation inside a template expression is never closed.
CodeSeverityReported when
PLAY0158ErrorA condition holds a token the language has no reading for.
PLAY0159ErrorA condition is expected and nothing is written.
PLAY0160ErrorA group opened in a condition is never closed.
PLAY0161ErrorA comparison states what is compared and not how.
PLAY0162ErrorA comparison states nothing to compare against.
CodeSeverityReported when
PLAY0163ErrorA construct opening an inline code block is followed by no fence.
PLAY0164ErrorAn inline code block is never closed.
CodeSeverityReported when
PLAY0165WarningA property names a type nothing in the document or its imports declares.
PLAY0166WarningAn event is referred to that nothing in the document or its imports declares, including projection remove with, remove via join on, and capture append.
PLAY0167Warning or errorA policy is referred to that nothing in the document declares. A persona’s unknown policy is an error during compilation, Safe authoring, and executable binding. Draft authoring retains it as a warning with explicit unresolved-reference debt; other unresolved policy references are warnings.
PLAY0168ErrorA concept and a type, or two of either, are declared under one name; also reused when an inline event repeats a typed payload property name.
PLAY0169ErrorAn authentication block declares two providers under one name.
PLAY0170ErrorA seed block seeds nothing.
PLAY0171ErrorA concurrency block narrows nothing.
CodeSeverityReported when
PLAY0172ErrorTwo files of a folder each declare something the application has at most one of.
PLAY0173ErrorTwo files of a folder declare the same name.
PLAY0174WarningTwo files of a folder describe the same thing differently, and the first description is kept.

What a command or reaction trigger reads to decide

Section titled “What a command or reaction trigger reads to decide”
CodeSeverityReported when
PLAY0175ErrorA reads line is not reads <ReadModel> [as <alias>] [by <value>] (or the header of a child by mapping block), or uses as, by, or reads as an alias. Under a reaction trigger, a bare reads line suggests @reads for a value named reads.
PLAY0177WarningA command or reaction trigger reads a read model no projection in the document produces.
PLAY0178WarningThe by of a command’s reads declaration does not name a property of the command.
PLAY0442WarningA reaction trigger reads by a value it does not take.
PLAY0443ErrorA clock trigger reads by a value, but clock triggers take no values.
PLAY0444WarningA reaction trigger reads a primitive type name as a view; use @reads <PrimitiveType> if reads is a trigger value.
PLAY0451ErrorA reads line in a command or reaction trigger has children other than one by block, or combines that block with a single by value. Invalid children are skipped, not parsed as owner values or properties.
CodeSeverityReported when
PLAY0179ErrorA require rule carries no condition.
PLAY0180ErrorThe body of a require rule holds something other than its message.
PLAY0181WarningA require operand is qualified by something the command does not read.
PLAY0182WarningA require operand names neither a property of the artifact nor state it reads.

CodeSeverityReported when
PLAY0183ErrorAn authentication provider carries a configuration body, which belongs where the application runs.
CodeSeverityReported when
PLAY0184ErrorTokens are left over after the requirement of an authorize.
PLAY0185ErrorA parenthesised group in an authorize is never closed.
CodeSeverityReported when
PLAY0186ErrorA readmodel line is not readmodel <Name>.
PLAY0187ErrorA reducer line is not reducer <Name> => <ReadModel>.
PLAY0188ErrorA line in a reducer body is not an on <EventType> rule.
PLAY0189ErrorA reducer declares no rule, so nothing it observes is stated.
PLAY0190ErrorThe body of a reducer rule holds something other than a description, a file or inline code.
PLAY0191ErrorMore than one projection or reducer builds the same read model.
PLAY0192ErrorA document declares the same read model more than once.
PLAY0398ErrorA reducer has some on rules with transition bodies and others without them. Give every rule an inline or file body.
PLAY0399ErrorA reducer observes the same resolved event in more than one on rule.

Where a produced event lands, and what a reaction sets off

Section titled “Where a produced event lands, and what a reaction sets off”
CodeSeverityReported when
PLAY0193ErrorA produces declares more than one for, and an event is appended to one event source.
PLAY0194ErrorAn invokes line is not invokes <Command>.
PLAY0195WarningA reactor invokes a command the document does not declare.
CodeSeverityReported when
PLAY0196WarningA screen binds data to a query nothing in scope declares.
PLAY0197WarningA screen navigates to a screen nothing in scope declares.
PLAY0198WarningA bare name matches more than one declaration at the same depth, or a qualified name matches more than one trailing container path, so which one it means is undecided. See declared dependency targets.
CodeSeverityReported when
PLAY0199ErrorA scoped line is not scoped to <scope>.
PLAY0200ErrorA query declares more than one scope, and results are narrowed one way.
CodeSeverityReported when
PLAY0201ErrorA ui profile line is not ui profile <Name>.
PLAY0202ErrorTwo ui profile blocks in the same document declare the same name.
PLAY0203ErrorA target line under a ui profile is neither target platform ... nor target size ....
PLAY0204ErrorA ui profile declares target platform or target size more than once.
PLAY0205ErrorA line under a packages block is not a valid package name.
PLAY0206ErrorA ui profile’s packages block lists the same package more than once.
PLAY0207ErrorA line in a ui profile body is not target or packages, or packages is declared more than once.
CodeSeverityReported when
PLAY0208ErrorA form line is not form <Name> for <Command>.
PLAY0209ErrorTwo form blocks in the same document declare the same name.
PLAY0210ErrorA line in a form body is not populate, field or on submit.
PLAY0211ErrorA populate line is neither populate via query ... nor populate from item.
PLAY0212ErrorA form declares populate more than once.
PLAY0213ErrorA field line is not field <property> [from <source>|compose using <Callback>] [label "..."].
PLAY0214ErrorAn on submit line is not on submit navigate to <Screen> [by <param>].
PLAY0215ErrorA form declares on submit more than once.
PLAY0216WarningA field binds to a property its form’s command does not declare.
CodeSeverityReported when
PLAY0217ErrorA contribute line is not contribute to <ContributionPoint>.
PLAY0218ErrorA line in a contribute to body is not navigate, label or order.
PLAY0219ErrorA contribution declares navigate to more than once.
PLAY0220ErrorA contribution declares label more than once.
PLAY0221ErrorA contribution declares order more than once.
PLAY0222ErrorA contribution’s label line is not label "..." or label $strings.....
PLAY0223ErrorA contribution’s order line is not order <number>.
PLAY0224WarningA contribution names a contribution point nothing in scope declares.
CodeSeverityReported when
PLAY0225ErrorA theme line is not theme <Name>.
PLAY0226ErrorTwo theme blocks in the same document declare the same name.
PLAY0227ErrorA line in a theme body is not compatible with <Package>.
PLAY0228ErrorA theme declares compatibility with the same package more than once.
PLAY0229ErrorA ui profile’s theme line is not theme <Name>.
PLAY0230ErrorA ui profile declares theme more than once.
PLAY0231WarningA ui profile selects a theme nothing in the document declares.
PLAY0232WarningA ui profile selects a theme not declared compatible with one of the profile’s own packages.
CodeSeverityReported when
PLAY0233ErrorAn arrangement line is not arrangement flow or arrangement freeform.
PLAY0234ErrorA layout, screen template or dialog template declares arrangement more than once.
PLAY0235ErrorA row, column or grid line in an arrangement is malformed.
PLAY0236ErrorA slot leaf within an arrangement tree has malformed sizing attributes.
PLAY0237ErrorA when override line in an arrangement is not a valid width/height size-class condition.
PLAY0238ErrorAn arrangement declares more than one when override for the same width/height size-class combination.
PLAY0239ErrorAn arrangement block’s body does not match its mode - a flow arrangement declares a variant, or a freeform arrangement declares anything other than one.
PLAY0240ErrorA variant line is not variant width <compact|regular>, height <compact|regular>.
PLAY0241ErrorAn arrangement declares more than one variant for the same width/height size-class combination.
PLAY0242ErrorA place line is not place <Slot> hidden or place <Slot> at x,y size w,h.
PLAY0243ErrorA variant places (or hides) the same slot more than once.
PLAY0244WarningA freeform arrangement’s variant does not mention (place or hide) a slot another variant of the same arrangement places.

These whole-model C# checks run after file assembly and also on programmatic syntax passed to the semantic binder. Public metadata and explicit direction select ESM v9 once these checks pass; a model that fails them never binds. Unknown and ambiguous references retain PLAY0166 and PLAY0198, rather than being guessed private/local. Private origins continue to use the existing invalid event/import declaration diagnostics.

CodeSeverityReported when
PLAY0607ErrorA command produces a public event. Move publication to an outbound Translate slice.
PLAY0608ErrorA local public event is produced outside an explicitly outbound Translate slice.
PLAY0609ErrorAn outbound Translate slice produces zero or multiple distinct local public event types. Repeated productions of the same type count once.
PLAY0610ErrorA foreign public event is consumed outside an explicitly inbound Translate slice.
PLAY0611ErrorAn outbound translation consumes a public or foreign event rather than a private local event.
PLAY0612ErrorAn inbound translation produces a public or foreign event rather than a private local event.
PLAY0613ErrorA foreign public event is produced locally. Translate it to a private event instead.
PLAY0614ErrorA Translate slice declares or uses public event metadata without explicit direction. Legacy translations without public metadata remain historically inbound. C# and the editors repair it when exactly one direction fits.
PLAY0615ErrorAn outbound translation contains an external-data capture instead of consuming private local events.
PLAY0616ErrorAn explicitly inbound translation consumes a private or local event instead of a foreign public event.
PLAY0617ErrorAn outbound translation produces a private event instead of its one local public event.
PLAY0618ErrorA projection or reducer targets an event (projection X => SomeEvent) outside an explicitly outbound Translate slice.
PLAY0619ErrorA capture reads source events outside an explicitly inbound Translate slice.
PLAY0620ErrorA source events block has no from <Event> line, a line that is not from <Event>, an invalid event name or a repeated event.
PLAY0687ErrorA capture’s source events originate from several event stores; split it into one capture per origin.

The operational edges checked are seed appends, command and reaction productions (including refusal branches), capture appends, projection event sources and joins/removals, reducers and constraints. Projection all includes every declared contract; every only maps the projection’s existing inputs. Specification fixtures are not operational edges. A projection or reducer whose => target resolves to an event (and not to a declared read model) is an event-target projection: its target counts as an output of the slice and its from/on events as inputs, so PLAY0609, PLAY0611, PLAY0613 and PLAY0617 apply to it, and PLAY0618 reports one outside an explicit outbound translation. Each from <Event> under source events counts as an input of the capture, so PLAY0610, PLAY0614 and PLAY0616 apply, and PLAY0619 reports source events outside an explicit inbound translation. Both forms bind and select ESM v9. Existing syntax restrictions remain: qualified reaction triggers do not parse, and qualified event productions still report PLAY0497. Programmatic qualified references are resolved and checked, not treated as private. The TypeScript compiler and both editors report the same codes (see editor diagnostics).

Repairs: only PLAY0614 has one. It declares direction inbound or direction outbound on the slice, and is offered only when exactly one direction is consistent with the slice’s events and constructs (C# propose-repair and read-workspace view repairs over MCP; the TypeScript quick fix in Monaco and VS Code). Every other code in this section has no automatic repair because each one is a contract decision for the author, not a spelling: PLAY0607, PLAY0608, PLAY0613 and PLAY0617 would change which events a slice publishes or produces; PLAY0609, PLAY0611, PLAY0612 and PLAY0616 would change which events a translation consumes or produces, or its direction; PLAY0610, PLAY0615, PLAY0618 and PLAY0619 would move a construct between slices or change its direction; PLAY0620 is malformed source events input with no single intended correction. PLAY0687 requires splitting a capture by origin, with no single intended correction.

CodeSeverityReported when
PLAY0663ErrorA reaction or refusal-branch production declares a stream route. Only command event productions can override a route.
PLAY0664WarningA production repeats its command’s source, stream and stream-id mappings. The typed workspace repair removes the override.
PLAY0665ErrorAn observer filter is malformed, duplicated, has children, names an unresolved or ambiguous source/stream, or a filtered reaction has a non-event trigger.
PLAY0666WarningA reaction or reducer filter excludes every statically known producer’s effective route. Handlers and foreign origins are unknown and suppress this C#-only warning.
PLAY0667ErrorEnum members mix explicit numbers with unnumbered members. Number all members or none.
PLAY0668ErrorAn enum declares the same number more than once; aliases are not supported.
PLAY0669ErrorAn enum member number is outside the int32 range.
PLAY0670ErrorAn enum member number is malformed: use decimal digits with an optional minus, no leading zero, fraction, exponent or plus.
PLAY0671InformationOpt-in completeness hint (enum-pinning or PLAY0671; also included in all) for an unnumbered enum used by an event property. Ordinary compilation does not report it. The numbering refactoring pins each member’s current position; this is not a correctness repair.
PLAY0672ErrorUnknown generation strategy; use the closed strategy set.
PLAY0673ErrorMissing or malformed generation argument or modifier value.
PLAY0674ErrorGeneration modifier not allowed for this strategy or primitive.
PLAY0675ErrorGeneration modifier repeated; write each at most once.
PLAY0676ErrorConcept declares generation more than once.
PLAY0677ErrorGeneration strategy incompatible with the concept primitive.
PLAY0678ErrorPrefix modifier is not printable ASCII or exceeds 32 characters.
PLAY0679ErrorNanoID alphabet must be distinct printable ASCII of size 2..256.
PLAY0680ErrorTypeID prefix is not empty or 1..63 lowercase letters/underscores starting and ending with a letter.
PLAY0681ErrorNanoID size outside 1..256 or bytes count outside 1..512.
PLAY0682ErrorBinding refuses reserved sequence generation until #619.
PLAY0683WarningGenerated property has fewer than 64 random bits; names the approximate 1% collision draw count. Suppressed when a unique constraint covers its mapped event property.
PLAY0684ErrorGenerated identifier has fewer than 64 random bits.
PLAY0685ErrorA returned name is used under the returning command’s on failure. Use it in on success instead; form fields and behavior parameters keep their existing meaning, and an outer successful response remains available.
PLAY0688ErrorA generated concept’s strategy can violate a rule. The diagnostic is on the rule and names the strategy and a quoted witness, regardless of the rule’s severity. Review the strategy-derived matches replacement repair; it also changes validation of input and stored values.
PLAY0689WarningConsistency is Unproven for a generated concept rule; names the opaque/outside-fragment/budget/timeout reason. Passing samples are not proof.

Overrides reuse PLAY0504 for route shape, mapping, destination type and duplicate-route errors. Protected sources reuse PLAY0515. Property paths remain refused at binding with PLAY0268 (#574), and generated route inputs with PLAY0273.

These checks run on the assembled model. The source stays in the syntax tree, so an authoring tool can still show and repair it.

CodeSeverityReported when
PLAY0621ErrorAn exposure for <Owner> header or one of its property lines is malformed, or names an unknown collection operation.
PLAY0622ErrorAn exposure’s owner is not a layout, screen template or dialog template.
PLAY0623ErrorRe-exposures of one component property form a cycle.
PLAY0624ErrorA reexposes <Owner> names an owner that does not expose the same component property.
PLAY0625ErrorAn instance header or one of its set, items, item or item value lines is malformed.
PLAY0626ErrorAn instance is not a screen, screen template or dialog template.
PLAY0627ErrorAn instance stores a value for a component property no exposure exposes.
PLAY0628ErrorAn instance uses set on a collection exposure, or items on a single-value exposure.
PLAY0629ErrorA template’s content <slot> names a slot the template does not declare.
PLAY0630ErrorA navigation’s outlet <name> names an outlet no layout, template or component declares.
PLAY0631ErrorA screen or scoped template assignment uses a template whose scopes exclude that scope.
PLAY0632ErrorA component comes from a package no ui profile declares. Only checked when at least one profile declares packages.
PLAY0654ErrorA navigation contribution’s destination outlet or destination dialog names an outlet or dialog template nothing declares.
PLAY0655ErrorA screen’s contribute to <Point> names a contribution point no layout or template slot declares. Unlike a module or feature contribute to (PLAY0224, a warning), screen contributions belong to the screen-composition checks.
PLAY0656ErrorTemplate content nests templates in a cycle: a template’s content uses itself, directly or through other templates.
CodeSeverityMeaning
PLAY0633ErrorInvalid identity header; write the bare identity keyword.
PLAY0634ErrorMore than one identity block in a document. A second file’s block uses the existing folder singular-declaration diagnostic.
PLAY0635ErrorInvalid typed detail line or escape source; each detail has exactly one source.
PLAY0636ErrorUnknown identity source kind; use from claim, from query, inline code or a file.
PLAY0637ErrorIdentity detail has neither a declarative source nor an implementation.
PLAY0638ErrorA claim/query detail has a body; refresh and caching belong to the runtime.
PLAY0639ErrorDuplicate identity detail name.
PLAY0640ErrorDetail redeclares id, name, userName, isAuthenticated, roles or claims.
PLAY0641ErrorIdentity query source names an unknown or ambiguous query.
PLAY0642ErrorIdentity source query is unkeyed or returns a list rather than one result.
PLAY0643ErrorIdentity query source omits by <expression>.
PLAY0644ErrorIdentity query key reads something other than token built-ins, claims or literals.
PLAY0645ErrorSource query’s authorization depends on additional identity details.
PLAY0646ErrorQuery result type or optionality does not match the declared detail type.

Unknown detail types reuse PLAY0165; unknown caller properties reuse PLAY0155. Executable detail reads report PLAY0268, naming the detail and its pending admission (#600). See identity details.

None of these has an automatic repair: each is a composition decision for the author.

CodeSeverityReported when
PLAY0660Errorkey is marked outside a top-level read-model property, combined with another modifier, or has an optional or collection type. A part of a multipart key cannot have a composite type.
PLAY0661ErrorA single-instance lookup omits key parts. The message names the missing parts. Command reads have a typed repair when every missing part has one same-named compatible source. Queries and trigger reads are not repaired. Scalar screen, form and navigation lookups cannot supply composite keys.
PLAY0662ErrorA by block has fewer than two distinct parts, names an unknown part, uses the wrong key shape or supplies an incompatible, optional, collection or literal source. A single-instance query must agree with the declared key. No automatic repair is offered.

An explicit single key binds byte-identically to an inferred identifier. Composite keys and by-block queries are authoring-only: binding reports PLAY0268 citing #599.

CodeSeverityReported when
PLAY0245ErrorA trigger line is not trigger <Name>.
PLAY0246ErrorA line in a trigger body is neither a description nor a value the trigger provides.
PLAY0247ErrorThe document declares two triggers by the same name, leaving no answer to which one a reaction means.
PLAY0248WarningA when line names neither an event nor a trigger the document or the compiler knows.
PLAY0249ErrorAn every line is not every <n> <seconds|minutes|hours|days>.
PLAY0250ErrorAn at line is not at <HH:mm>, optionally followed by on <Weekday> or on day <n>.
PLAY0251WarningA reaction takes a value from an occurrence that the trigger does not provide.
PLAY0252ErrorA reaction states more than one where, and a reaction is narrowed by one condition.
PLAY0253ErrorA reaction declares the same trigger more than once, so the second says nothing the first did not.
PLAY0450ErrorA value line appears under an every or at reaction trigger; clock triggers take no values.

Layouts, screen templates and dialog templates

Section titled “Layouts, screen templates and dialog templates”
CodeSeverityReported when
PLAY0254ErrorA screen template line is not screen template <Name>.
PLAY0255ErrorA dialog template line is not dialog template <Name>.
PLAY0256ErrorA fits slot line is not fits slot <name>.
PLAY0257ErrorA screen template declares fits slot more than once.
PLAY0258ErrorA layout or a dialog template declares fits slot - neither fills a slot of a parent structure.
PLAY0259ErrorA top level layout line is not layout <Name>.
PLAY0260ErrorA document declares more than one layout by the same name.
PLAY0261ErrorA ui profile’s layout line is not layout <Name>.
PLAY0262ErrorA ui profile declares layout more than once.
PLAY0263WarningA ui profile selects a layout nothing in the document declares.
CodeSeverityReported when
PLAY0264WarningA file directive names an absolute path, and a file reference is relative to the repository root.

A path that does not resolve is not a diagnostic, at any severity. A document is read in a designer, in a build and on a machine where the tree is not present, so the compiler never holds a path against a file system - a stale path must not be what makes a valid document invalid. A consumer that can resolve paths decides for itself what an unresolvable one means.

CodeSeverityReported when
PLAY0265ErrorA then query line does not name a query.
PLAY0266ErrorA line in a then query body is neither arguments nor result.
PLAY0267ErrorA then query assertion declares arguments more than once.
CodeSeverityReported when
PLAY0268ErrorSource syntax carries behavior the supported ESM profile cannot represent, including query filters with from, single-result filters, invalid same-name/scalar/type filter shapes, explicit query scopes and performers, compliance on identity or enum concepts, events combining personal or explicitly subject-scoped secret values with an explicit subject mark, generated properties whose concepts declare validation rules, and unsupported scalar $context produces paths (tenant is not event namespace; claims and roles are not portable scalar values), an unsupported validation rule, concept require, command require or production conditions over read-model paths (#129), date/today conditions, non-deterministic $env conditions, $context tag values, and a bare named rule with no implementation body (see Commands). Bodied named rules, command/concept code validation, and inline/file policy predicates bind as opaque ESM v3 attachments rather than reporting this diagnostic.
PLAY0269InformationSource syntax is explicitly deferred from the current backend semantic profile.
PLAY0270InformationSource syntax, including a valid persona, compliance reasons and event subject marks, is realization or authoring/operational metadata rather than portable behavior. Event id pins are executable stored names from ESM v16.
PLAY0271Information or errorSource syntax keeps its legacy meaning and cannot be strengthened into ESM v1 implicitly.
PLAY0272ErrorSource syntax requires an explicit reviewed semantic migration before binding.
PLAY0273ErrorSyntax and identity information cannot produce a coherent semantic compilation, including reserved stored source Default or stream All names (also through id pins), stored-name collisions, an event-source for assertion without one unambiguous required scalar command destination type or a produces mapping, then event expectation, projection mapping, or constraint naming a property absent from the current event revision, or an authorization policy, property rule or requirement referencing a generated value before generation.
PLAY0274ErrorA syntax location cannot be mapped to a supplied semantic source document.
CodeSeverityReported when
PLAY0275ErrorA specification event-source assertion is a bare for and does not provide a value.
PLAY0276ErrorOne specification command or event step declares its for <value> event-source assertion more than once.
CodeSeverityReported when
PLAY0277ErrorA variant line is not variant <Name>.
PLAY0278ErrorA variant declares no enters on event, so nothing ever activates it.
PLAY0279ErrorAn enters on line is not enters on <EventType> [key <expression>].
PLAY0280ErrorA variant is declared inside another variant, and variants do not nest.
PLAY0281ErrorTwo variants of the same projection declare the same name.

These structural warnings run only when selected, after error-free whole-application source compilation. See Completeness checks for selection and exemptions and editor diagnostic support for the TypeScript/C# boundary.

CodeSeverityReported when
PLAY0530Warning (opt-in: --check data-bindings)Visible screen bindings share a name but disagree on cardinality, resolved query or by parameter. Identical rebinding and sibling sections are allowed.
PLAY0531Warning (opt-in: --check data-bindings)A screen binding’s resolved read model or cardinality differs from its query’s return. Optional and observable qualifiers are ignored; unresolved or ambiguous names are skipped.
PLAY0532Warning (opt-in: --check input-surfaces)An action has no module-level command-bound form or issuing screen in the command’s own slice. Post-action navigation does not supply input; a title-only screen does not issue a command. Commands with only generated properties (including no properties) require no typed input.
PLAY0533Warning (opt-in: --check input-surfaces)A StateChange command has no used screen action or attached behavior execute, and no reaction invokes it. A form alone is not an issuer; attached navigation or open dialog may reach an issuing screen. Automation and Translate commands are exempt.
PLAY0534Warning (opt-in: --check field-origins)A declared read model has no builder or performer, or a top-level field lacks an identity, mapping, compatible AutoMap source, child or nested target. Variants are checked independently, including entering-event AutoMap; the owning slice’s keyed-query property counts as identity. Opaque builders and unknown coverage are skipped.
PLAY0535Warning (opt-in: --check query-keys)A query parameter cannot be held by its view’s known identity or fields. Identity comes from the owning slice’s unambiguous keyed-query property or structurally resolved projection keys. Performer-served views, tenant-context parameters and unknown identity types are skipped.
PLAY0536Warning (opt-in: --check event-consumers)The newest generation of a local event has no declared projection, reducer, reaction, constraint or interaction consumer. Specifications and production do not count. Imported external contracts are exempt; legitimate terminal facts may still be reported.
PLAY0537Warning (opt-in: --check navigation)A screen is unreachable from contributions or attached shell-level behaviors, including through screen actions, row clicks, behaviors, discovered forms or opened dialog templates. Unattached named behaviors and unreachable cycles do not establish entry points. With no entry points, one application finding reports that no screen is reachable.

These errors are reported by ordinary compilation, including compilation of a folder as one application; semantic binding is not required. References resolve from the innermost scope outward. Unknown or ambiguous declarations and imported shapes are not guessed.

CodeSeverityReported when
PLAY0282ErrorA declarative validate rule targets a field absent from the command’s declared shape, including named rules with implementation blocks. A dotted path is followed through declared composite types; continuing past a primitive, concept or enum field is reported, while a path through an undeclared or imported type is left undecided.
PLAY0283ErrorThe type supplied by reads <View> by <field> is incompatible with every declared query by parameter of that view. Filter parameters do not substitute for a key. Parameter names may differ; distinct concepts remain distinct types.
PLAY0284ErrorA children or nested block never populates a declared element field through its identity, explicit mappings, inherited every mappings, nested blocks, joins, or compatible AutoMap. Coverage is across the block’s events, not a requirement that every update event fill every field.
PLAY0285ErrorA specification’s expected event contradicts every possible declared producer of its when command, using decidable literals, property copies and equality conditions.
PLAY0286ErrorA specification value is not a member of the enum declared by that specific command, event, read-model field or query parameter. Bare members, qualified members and quoted member names are accepted.
PLAY0287ErrorA command or reaction producer, a capture append mapping, or a specification’s given/then event step, assigns a field absent from the referenced event’s declaration. Dotted paths follow the same rule as PLAY0282: title.missing is reported when title is a primitive, concept or enum, detail.missing when Detail is a declared type without that field. A collection or optional composite field is addressed element-wise.
PLAY0290WarningAn import names an event, command, read model, concept or type the application declares itself. The declaration is what every reference resolves to and what these checks see, so the import has no effect - remove it.
PLAY0291ErrorA mapping value starts with { or [ but is not a valid single-line JSON object or list (keys must be quoted).
PLAY0292ErrorAn object key does not name a property of the target’s declared composite type. Unknown or imported types remain undecided.
PLAY0293ErrorA statically known value has the wrong shape for its target: a collection expects a list, a declared composite expects an object, and a scalar cannot accept a list or object.
PLAY0294ErrorAn inline JSON object repeats a key (including inside a nested object or list); each property may be stated once.

An import never changes what these checks see: a name the application declares resolves to that declaration whether or not it is also imported, and an imported name nothing here declares keeps an unknown shape.

These checks do not execute handlers, custom predicates or opaque expressions. An undeclared query signature does not establish a read-key mismatch. An unknown event shape under AutoMap, or an open all subscription with AutoMap, leaves projection coverage undecidable. Outcome checks compare explicit producer mappings only; they do not invent mappings for omitted fields.

Concept compliance markers, qualifiers and secret scopes are admitted by ESM v13. PLAY0268 refuses compliance on enum or event-source/stream identity concepts and refuses an event containing personal or explicitly subject-scoped secret values together with an explicit subject mark until lineage is admitted. The latter check is source/binder-only: subject marks have no ESM bytes. PLAY0515 still rejects protected identities during source validation. The strict reader and programmatic validator refuse compliance below v13, unknown special categories or scopes, secret scope next to personal, and compliance on enum or identity concepts. Reasons remain report-only (PLAY0270).

Caller-supplied equality filters on collection queries are admitted by ESM v14. PLAY0268 names the query, filter and reason for a refused filter: it has a from source, returns a single result, lacks a same-named scalar primitive/concept/enum property, differs in nominal type (ignoring optionality), repeats a name or duplicates by. Explicit scope, performer and context-sourced by each have their own refusal. The strict reader and evaluator reject unknown/repeated filter values, missing required filters, null and type mismatches. PLAY0468 applies to unknown/repeated/missing required specification arguments in both query spellings. See Queries.

For executable-model dispositions, see PLAY0268–PLAY0271 above, projection semantic-model admission, what the executable model admits for commands, and constraints.

CodeSeverityReported when
PLAY0288WarningAn accepted AST authoring operation canonically prints a touched document. The message states how many comments could not be retained and on which lines; attached comments follow their syntax owners, whitespace is normalized, and untouched documents retain their exact bytes.
PLAY0289ErrorAn empty authoring workspace has no source documents to compile to an executable model. You can still propose its first typed document.

Source-authoring acceptance and executable readiness are separate verdicts. An authoring proposal validates the complete .play application and identity continuity without claiming that every language construct is supported by the executable backend profile. Executable-only workspace transactions remain strict.

Every $eventContext.<path> - in a projection expression or in a dynamic dictionary key such as countByType.$eventContext.eventType.id - is checked against the event context catalog. Chronicle resolves the path by reflection when it builds the projection and fails on one it cannot resolve, so this is the only place the mistake can be caught early. An unlisted member is a warning because a runtime may resolve more than the catalog lists; a path that can never resolve is an error.

CodeSeverityReported when
PLAY0295WarningAn $eventContext.<path> opens with a member the event context does not have, such as $eventContext.causationId. A member resolves written camelCase or with only its first letter uppercased.
PLAY0296WarningAn $eventContext.<path> continues into something the member before it does not have, such as $eventContext.eventType.name. The derived function Week is case-sensitive: occurred.Week resolves and occurred.week does not.
PLAY0297ErrorAn $eventContext.<path> continues below causation or tags. They are collections with no addressing grammar, so a path below them never resolves.
PLAY0298ErrorAn $eventContext reference names no member, as in $eventContext. or a dynamic key ending in .$eventContext, or has an empty segment.
PLAY0299WarningA dynamic dictionary key names a $ source other than $eventContext, such as byUser.$causedBy.subject. Only $eventContext.<path> is resolved; any other source becomes the literal key. Write byUser.$eventContext.causedBy.subject.
CodeSeverityReported when
PLAY0350ErrorA command or event specification value is null; in Chronicle an optional fact is a separate event. Optional read-model values may be null.
PLAY0351ErrorA given readmodel or then readmodel block does not state every declared key part, or its inferred identifier when no key is declared. A scalar then query … result block may derive its identifier from the argument.
PLAY0352ErrorA specification without an action asserts an event or error, or has no read-state/query outcome. One actionless query with one error and no other outcome is admitted as a Validation rejection from ESM v18; an error without a query remains invalid.
PLAY0353ErrorA specification value is null for a required property, or a nested command/event property is null; only optional read-model properties admit null.
PLAY0354ErrorA structured specification object omits a required property of its declared composite type.
PLAY0355ErrorThe composite type declared for a structured specification value cannot be resolved.
PLAY0356ErrorA typed structured specification object repeats a member; inline JSON duplicates are caught earlier by PLAY0294.
PLAY0357ErrorAn ESM message beginning with $strings. has no valid dotted key. Keys follow .strings assignments: an ASCII letter or underscore first, then word characters; subsequent segments contain one or more word characters.
PLAY0358ErrorA specification declares more than one when action (command or appended event).
PLAY0359Errorthen events in any order is malformed or repeated.

The interaction model - behaviors, the on clauses that start them, the actions they run and the continuations those actions branch into. The fifty codes from PLAY0300 upwards are reserved for this band as a whole, so a later addition lands beside its siblings rather than wherever there happened to be room.

A behavior is deferred from the backend ESM v1 profile in the same way every other UI construct is - see PLAY0269. Deferred does not mean droppable: the syntax tree, the printer and the semantic model carry every interaction construct in full, and a target that cannot realize one reports it rather than dropping it.

CodeSeverityReported when
PLAY0300ErrorA behavior declaration is not of the form behavior <Name>.
PLAY0301ErrorA behavior name is declared more than once.
PLAY0302ErrorA line in a behavior body is neither description, parameter, order nor an on binding.
PLAY0303ErrorA behavior parameter declaration is not of the form parameter <name> [<Type>].
PLAY0304ErrorA behavior declares the same parameter name more than once.
PLAY0305ErrorA behavior order is not an integer.
PLAY0306WarningA behavior declares no bindings, so nothing it is attached to can run anything.
PLAY0307ErrorAn on clause names neither a built-in interaction kind, an event, an interval, nor a declared application trigger.
PLAY0308ErrorAn interaction binding declares no actions.
PLAY0309ErrorAn interaction binding declares where more than once.
PLAY0310ErrorA line where an action was expected does not name one of the action kinds.
PLAY0311ErrorAn execute action is not of the form execute <Command>.
PLAY0312ErrorA navigate action is neither navigate to <Screen> nor navigate back.
PLAY0313ErrorAn open dialog action does not name a dialog template, or a close action is not close dialog.
PLAY0314ErrorA refresh action does not name a query.
PLAY0315ErrorA set action is not of the form set <target> to <value>.
PLAY0316ErrorA notify action is not of the form notify <info|warning|error> "<text>".
PLAY0317ErrorA confirm action carries no message.
PLAY0318ErrorA raise action does not name an application trigger.
PLAY0319ErrorAn action argument is not of the form with <name> from <binding>.
PLAY0320ErrorA continuation is attached to an action that cannot fail, so it could never run. navigate, notify, set and close dialog have no outcome to branch on.
PLAY0321ErrorAn on result continuation is attached to something other than open dialog.
PLAY0322ErrorA uses clause is not of the form uses <Behavior>.
PLAY0323ErrorAn argument at a uses site is not of the form <parameter> <value>.
PLAY0324ErrorInteraction nesting went deeper than the compiler admits. Extract the inner actions into a named behavior.
PLAY0325WarningAn interval trigger is below the floor a client can usefully honour.
PLAY0326ErrorAn application trigger is declared with a name reserved as a built-in interaction kind. on <Name> would mean the interaction and never the trigger, so the declaration would be unreachable.
PLAY0330WarningAn action names a command the document does not declare.
PLAY0331WarningA navigate to action names a screen the document does not declare.
PLAY0332WarningA refresh action names a query the document does not declare.
PLAY0333WarningAn open dialog action names a dialog template the document does not declare.
PLAY0334WarningA raise action or an on clause names an application trigger the document does not declare.
PLAY0335WarningAn on event clause names an event the document does not declare.
PLAY0336WarningA uses clause names a behavior the document does not declare.
PLAY0337ErrorA uses site supplies an argument the behavior declares no parameter for.
PLAY0338ErrorA uses site leaves a behavior parameter without an argument.
PLAY0339WarningActions follow an unconditional navigation, so they could never run.
PLAY0340WarningAnother file of a folder repeats an attachment of the same module or feature - a uses of the same behavior with the same arguments, or an inline on block identical to one already attached. Only the first, in file-path order, is kept; the repeat is ignored and the warning names the file that attached it first. Folders written by earlier versions restate a module’s or feature’s attachments in every descendant file, and report this once per copy.
PLAY0341ErrorA guarded action child is not when <condition> execute <Command>, otherwise hidden, otherwise execute <Command> or navigate to …; navigation is repeated, or otherwise hidden has command arguments.
PLAY0342ErrorA label-headed guarded action declares no when alternatives.
PLAY0343ErrorA guarded action repeats otherwise, or declares a when alternative after it.
PLAY0344ErrorA guarded action condition does not compare an item.<field> path with a literal. Ordering operators require a number; contains and starts with require a string.
PLAY0345WarningAn item path in a guarded action condition or input binding names no subject field, continues past a scalar, or crosses a collection-valued field.
PLAY0346WarningA guarded action has no nearest data subject, or multiple data directives tie in its nearest container. Field checks are skipped until the subject resolves.
PLAY0347WarningEarlier alternatives provably shadow an alternative. Guards use first-match order; proof uses DNF comparison-set inclusion with a 64-disjunct expansion cap. Overlap alone is not reported.
PLAY0348WarningA guarded alternative or otherwise execute supplies a with argument the chosen command does not declare, or binds a subject field whose collection cardinality differs from the command input.

Guarded-action checks PLAY0341–PLAY0348 are shared by the TypeScript compiler, Monaco and VS Code. Subject and command shapes that are imported but undeclared, or ambiguous, remain unknown rather than guessed. See Editor diagnostic support for the remaining C#-only checks.

An inline on block is an anonymous behavior, so it has no name to report against. Diagnostics inside one cite the position and the trigger instead.

CodeSeverityReported when
PLAY0366ErrorA bare named matches pattern is not defined; only email is defined. Use a quoted ECMAScript pattern for custom matching.
PLAY0367ErrorA quoted matches operand is not a valid ECMAScript regular expression.
PLAY0368ErrorA validation rule names a severity other than information, warning or error.
PLAY0369ErrorA require body has an invalid or repeated severity directive.
CodeSeverityReported when
PLAY0380WarningA projection construct binds, but Chronicle’s projection lowering drops part of it: all inside a children or nested block loses its subscription to every event type and behaves as every, and an automap or no automap on a joined event is replaced by the auto-map of the level the join sits in.
PLAY0381WarningA projection-level key is parsed but does not route events in Chronicle or the executable semantic model. Declare keys on each from (or its events).
PLAY0382ErrorA variant declares no enters on event.
PLAY0383ErrorA projection-level shared handler maps a property absent from a variant’s known read-model shape. Unknown shapes remain undecided.
PLAY0384ErrorTwo variants in one projection have the same name.
PLAY0385ErrorAn entering event is claimed more than once in one projection.
PLAY0386ErrorA given caller line is not authenticated, role "<name>", or claim "<type>" = "<value>".
PLAY0387ErrorA specification declares more than one given caller block or then denied outcome.
PLAY0388Errorthen denied contains extra text or is mixed with another outcome.
PLAY0389ErrorA specification exercises an authorized command or query without a given caller fixture or given caller as <Persona>.

These diagnostics cover constraint binding and the parser warning for file-backed constraints.

CodeSeverityReported when
PLAY0390ErrorA unique constraint names an event the application does not declare.
PLAY0391ErrorA unique <property> on <Event> constraint names a property the event does not declare.
PLAY0392ErrorTwo constraints in the application share a name. The name is a constraint’s identity in the event store - it keys the constraint’s index and its violations - so it is unique across the whole application, not just its slice.
PLAY0393Errorignore casing is declared on a unique event constraint; it applies only to unique property values.
PLAY0394WarningAnother file declares an identical authorize gate on the same module or feature. The first is kept and the repeated gate is ignored; distinct gates accumulate with AND.
PLAY0396WarningA file <Path> constraint names a Chronicle IConstraint class, which can only declare uniqueness. Use unique ... for portable uniqueness; put other rules in command validation or a require condition.

Use an opening fence with an info string, such as ```csharp (without the spaces), for every inline implementation. Use ```text for multiline descriptions. The old language-line form, validate csharp, and bare description fences still parse during the deprecation window; printing a document converts them to the new form.

CodeSeverityReported when
PLAY0397WarningAn inline code block uses a separate language line, validate csharp, or a multiline description uses a bare fence. The message names the tagged-fence replacement.

A compiler-authored typed repair is offered only when PLAY0397 identifies a validate csharp header. It uses an identity replacement and canonical printing to produce a tagged ```csharp fence. The entire file is reprinted; other legacy forms and whitespace may change, but a repair that would drop any comment is refused. Preview it through the revision-checked AST authoring contract (or MCP read-workspace repairs / propose-repair); review the bytes before applying. Other legacy forms are not individually offered as repairs.

Repeated command or reaction-trigger reads

Section titled “Repeated command or reaction-trigger reads”
CodeSeverityReported when
PLAY0410ErrorA command or reaction trigger reads the same view more than once without an alias on every instance.
PLAY0411ErrorTwo reads in a command or reaction trigger use the same alias.
PLAY0412ErrorA reads alias collides with a command property or reaction trigger value.

Implementation attachment loading (host-supplied)

Section titled “Implementation attachment loading (host-supplied)”

These warnings are returned by AttachmentFiles.Load for implementation files that remain UnresolvedFile. Syntax compilation alone does not read files.

CodeSeverityReported when
PLAY0430WarningAn attachment path is absolute, drive-qualified, escapes the model root, or is not portable.
PLAY0431WarningAn attachment or a directory on its path is a symbolic link or reparse point.
PLAY0432WarningAn attachment or a directory on its path is missing.
PLAY0433WarningAn attachment exceeds 2 MiB or the attachment set exceeds 8 MiB.
PLAY0434WarningAn attachment cannot safely be read as UTF-8 text.
CodeSeverityReported when
PLAY0445WarningA v1–v3 flat executable-model projection transition carries deprecated ZeroOrOne or Many affected-instance cardinality. Chronicle routes one key per transition; use a join for structural many. Returned by ExecutableSemanticModel.DeprecationDiagnostics for constructed or deserialized ESM, with a model-level location because ESM does not retain source positions. The source binder produces only One; query cardinality is unaffected.
PLAY0449ErrorA given fact needs a historical event shape (message names the event and revision), which Screenplay does not consume yet; or an event’s source revision disagrees with its persisted catalog revision and requires explicit forward advancement. There is no fallback from current to historical properties.

See Imports.

CodeSeverityReported when
PLAY0454ErrorAn import inside a module or feature does not name files as import "<path or glob>".
PLAY0455WarningA file import pattern with wildcards matches no .play file.
PLAY0456ErrorA file import names one file, without wildcards, and that file does not exist.
PLAY0457ErrorTwo imports place the same file in a module or feature where neither lies inside the other. A file belongs in one place.
PLAY0458ErrorImports keep placing a file deeper than 32 levels - they form a cycle.
PLAY0459ErrorA file imported into a module or feature declares a module other than the one it is placed in. Restating the module it is placed in is allowed.
PLAY0460ErrorThe top level of a file imported into a module or feature holds something that scope cannot hold, such as a screen template in a file placed in a feature.

Refusal branches, redelivery and no-event assertions

Section titled “Refusal branches, redelivery and no-event assertions”

Refusal branches and $refusal values bind and execute from ESM v19. Redelivery and then no events bind and execute from ESM v17; earlier strict readers reject their respective canonical members.

CodeSeverityMeaning
PLAY0538ErrorAn on refused header is malformed, uses an unsupported selector, or appears outside an invokes block. Use on refused [by validation | by constraint [<Name>] | by authorization].
PLAY0539ErrorA refusal branch is empty, repeats or adds children to acknowledge, combines acknowledgement with productions, or contains another kind of effect. Use acknowledge alone or one or more produces <Event> blocks.
PLAY0540WarningA refusal branch is shadowed by an earlier selector, or its declared constraint targets none of the invoked command’s events. Bare refusal covers validation and constraints, not authorization.
PLAY0541ErrorA $refusal value is outside a branch’s event mapping, has an unknown member, uses constraint outside a constraint selector, or targets an incompatible property type. The values reason, constraint and message are String values.
PLAY0542ErrorA named constraint in a refusal selector does not resolve to a declared constraint.
PLAY0557WarningAn on refused by authorization branch invokes a command gated by its own, feature or module authorization without a declared invoking identity. With no caller the reference runner always refuses the command. Arc runs commands as the system only for a reactor carrying [ExecuteCommandsAsSystem]. Declare runs as system role "<Role>" to state the intended identity; it suppresses this warning and selects released ESM v10. Refusal branches select ESM v19.
PLAY0543Errorwhen redelivered <Event> to <Reaction> is malformed, or its values, optional for and route locator do not identify exactly one definitely matching given event occurrence with no undecidable candidates. Use for, values, stream or no stream to narrow the locator.
PLAY0544ErrorThe redelivery reaction is unknown or ambiguous, or has no event trigger on the stated event.
PLAY0545Errorthen no events is malformed, repeated, has child mappings, or accompanies event, event-order, error or denial expectations. Use one leaf assertion after an action, including when append; read-model, query and response assertions may accompany it.

runs as is admitted by released ESM v10; PLAY0268 no longer refuses reaction command identity. Omitting it preserves existing executable bytes. System claim conditions evaluate to unknown and a final unknown denies.

CodeSeverityMeaning
PLAY0647Errorruns as is malformed, repeated or misplaced, or contains an empty or duplicate role. Use one reaction-level runs as system [role "<Role>" and role "<Role>"] line. Roles are quoted literals; zero roles is allowed.
PLAY0648WarningA reaction invokes a command with its own or inherited authorization gate without declaring runs as. Both compilers report at most one finding per invocation; an authorization refusal branch receives PLAY0557 instead.
PLAY0649WarningThe reaction declares identity but has neither invocations nor an inline or file implementation body. Both compilers check this.
PLAY0650WarningC# binder only: a declared role is referenced by no invoked command’s effective gate. Opaque gates and inline or file reaction bodies suppress this least-privilege finding.
PLAY0651WarningC# binder only: the declared system identity definitely cannot satisfy an invoked command’s effective gate. Claim conditions and other unknown results are not treated as definite denial.
PLAY0652Warning / InformationOpt-in privilege completeness: each producer of an elevated reaction’s trigger event must require every declared system role. Ungated commands, captures and reaction productions produce Warning; opaque gates produce Information because they cannot be compared. Clock and application triggers have no producer and are silent.

See Refusal branches, Redelivery specifications and Specification syntax.

See Specifications.

CodeSeverityReported when
PLAY0461ErrorA given clock or when clock does not state one ISO 8601 instant with an offset or Z, or given clock is repeated.
PLAY0462ErrorA when trigger line is not when trigger <Trigger>.
PLAY0463ErrorA given capture or when capture line is not <given|when> capture <Capture>.
PLAY0464ErrorA when query line is not when query <Query>, a then result line is not then result [exactly], or then no result is malformed or repeated.
PLAY0465ErrorA query result is asserted without when query, a performed query asserts no outcome, results conflict with no result, or a query error is combined with an action, multiple calls/errors, a result, then no result, denial or another outcome. Both compilers share the query-error shape checks; executable v18 admission and Validation comparison remain C# checks.
PLAY0466WarningA when trigger names a trigger nothing declares or registers, or a value its declaration does not carry.
PLAY0467WarningA given capture or when capture names a capture the application does not declare.
PLAY0468ErrorA when query or then query … arguments argument is unknown or repeated, or a required by or filter argument is missing.

These codes cover inline command events and event metadata.

CodeSeverityReported when
PLAY0469Warning (inline), information (plain)A production copies the command identifier into payload while targeting that same identifier. The inline-only repair removes the property and mapping, explicitly changes the event contract, retires its property address, and is excluded from fix-all. Consumers, opaque implementation impact or comment loss refuse the repair. Plain/standalone contracts receive guidance only: review persistence and generation evolution before changing their shape.
PLAY0470ErrorA command targets another event source but one or more productions omit for, or both an inline and a plain production omit for and therefore have different defaults. The diagnostic names the production. State every destination explicitly; cross-source execution is still unsupported.
PLAY0471InformationAn event’s id equals its current name. The typed removal repair covers inline and standalone declarations, preserves the executable model and catalog, and refuses comment loss. Monaco and VS Code also offer an editor quick fix to remove the complete line unless it has a trailing comment.
PLAY0472ErrorEvent id is missing its nonempty quoted value or is repeated.
PLAY0686Warning (retired)No longer reported: ESM v16 carries event id pins as stored type names under decision 0075. Retained for compatibility with earlier compiler warnings. See event rename pins.
PLAY0473ErrorAn inline event name collides with a standalone declaration, import, or another inline declaration.
PLAY0474Errorproduces event occurs outside a command, such as in a reaction.
PLAY0475ErrorAn inline event declares generation in its header or body. Extract it before evolving generations.
PLAY0476ErrorA production supplies unescaped system-assigned namespace, sequence, correlation, causation, causedBy, or occurred, or an inline event supplies origin.
PLAY0477ErrorEvent documentation is not one nonempty fenced Markdown block, or is repeated.
PLAY0558ErrorModule, feature, slice, command, read-model or reaction documentation is not one nonempty fenced Markdown block, or is repeated.
PLAY0559WarningFiles give different documentation for one module or feature. The first documentation is kept.
PLAY0572ErrorA given caller as <Persona> reference is malformed, has body lines, or names an unknown top-level persona. Unknown references list declared personas.
PLAY0573ErrorA persona caller cannot be synthesized or verified against its policies. Binding names the persona, policy and refusal (negation, nonLiteralClaim, roleClaim, opaqueImplementation, unresolvedPolicy, noPolicies); use an explicit given caller.
PLAY0574WarningOpt-in personas check: none of a persona’s policies gates a command, query or inherited screen scope.
PLAY0575WarningOpt-in personas check: an effective command or query gate definitely denies every declared persona’s synthesized caller; unsynthesizable or undecidable callers are unknown.
PLAY0576InformationOpt-in personas check: required atoms do not pin an or with multiple buildable alternatives. Names an unchosen alternative and suggests adding a policy that pins it.

Malformed typed mappings and duplicate destinations retain PLAY0044 and PLAY0193. Descriptions retain their existing diagnostics. Event descriptions and documentation retain their information diagnostic (PLAY0270). Event rename pins that differ from the event name select ESM v16 and carry storedName; equal-name pins keep the earlier version and bytes, and PLAY0686 is retired. Invalid pins, generation disagreements and stored-name collisions use PLAY0472.

CodeSeverityReported when
PLAY0478InformationA plain produces <Event> omits for and its command has one required scalar identifier. Conditional productions and optional or collection identifiers are not reported.

PLAY0478 does not change routing or executable-model bytes. Its typed repair replaces the production with one that explicitly states for <identifier>. Accept it only when that event should address the command’s identifier: a plain omission can intentionally use an allocated identity, or inherit another production’s explicit destination. The repair is not offered for an optional or collection identifier. It is also refused when the original or candidate has no executable model, when the repair would change the language or semantic version, or when any other production’s effective destination would change (including through a command default). Discovery verifies these conditions and comment preservation once per subject on an immutable workspace snapshot; a new snapshot cannot reuse those verification results.

The verified PLAY0478 repair is available through the MCP repair workflow. Monaco and VS Code do not offer a quick fix for PLAY0478 or PLAY0470.

For PLAY0166 on a command production, a typed repair can add an event declaration to the producing slice. Properties follow mapping order; command property paths retain their types and concepts (including compliance markings), and $context.occurred becomes DateTime. No generation, tags, subject or origin is inferred. Unknown sources, literals, computations, reads, conflicting producer shapes, imported or already-declared events, and cross-file producers have no repair. Any workspace document with parser errors also blocks inference, because its partial syntax may hide a contract or another producer. Reaction and capture producers are not inferred.

Both repairs require canonical formatting consent and refuse any dropped comment. Discovery verifies authoring acceptance for PLAY0166 too: an inferred event whose fields conflict with a specification is not offered. Discovery reuses cached acceptance and conflicts on the same immutable workspace snapshot; diagnostics are never cached. Every proposal runs one fresh transaction, even after discovery. A matched repair that fails returns that transaction’s typed conflicts and full diagnostics; UnknownRepair means no recipe matches the code and original subject, not a verification failure. Discovery and preview never write source. Review the write plan and explicitly accept it through the workspace authoring contract or MCP repair workflow. Stale workspace or catalog revisions are rejected. Source authoring and executable readiness remain separate; for example, compliance attributes and nested mapping paths can require capabilities the executable model does not yet admit.

CodeSeverityReported when
PLAY0479InformationA type uses the legacy optional suffix. Write optional after the type. This does not fail --warnaserror.
PLAY0480Erroroptional follows identifier. Write the modifiers in the order Type optional identifier; command identifiers must still be required and scalar.
PLAY0481ErrorA read uses optional. Optional reads are not yet supported; their absence behavior is reserved for #308.

query Q => observable? is the sole exception: its ? is the only spelling that preserves a one-shot query returning an optional scalar type named observable. It produces no PLAY0479 and is excluded from occurrence repairs and document migrations. See Queries.

PLAY0479 points at the complete type reference. VS Code marks it deprecated. Its workspace repair replaces only the spelling at that occurrence; a document repair combines all such replacements in one verified transaction. Both reparse the result, require unchanged syntax structure, and check that the selected information diagnostics disappear. Use PreserveTrivia to keep comments, alignment, line endings and encoding. Canonical reprinting is a separate explicit choice. Discovery and preview never write files; acceptance still requires current workspace and catalog revisions. Monaco and VS Code also offer verified TypeScript quick fixes for one occurrence or the entire document, without requiring .NET.

Generated properties, command responses, generated fixtures and return expectations are admitted as ESM v7. A pre-generation reference from authorization (including inherited/composed policies or a generated identifier’s implicit subject), a property rule or a requirement reports PLAY0273: reference an input property or remove generated. Rules on a generated concept select ESM V20: Proven rules are silent, Refuted rules report PLAY0688 with a witness and Unproven rules report PLAY0689 with a reason. Earlier ESM readers refuse these rules rather than drop them; fixtures are checked after shape validation, with failures rejected as Contract and opaque predicates remaining Unsupported. Missing generation fixtures bind, but reached generation returns Unsupported(IdentityAllocation) and cannot pass a specification. Other unadmitted constructs still block executable binding. See commands and fixtures.

For response and generated-fixture compatibility checks only, Date values must be quoted yyyy-MM-dd calendar dates. DateTime values must be quoted yyyy-MM-ddTHH:mm:ss, optionally followed by a decimal fraction of 1–7 digits, and always end in uppercase Z or an explicit +HH:mm / -HH:mm offset. Years range from 0001 to 9999; calendar days must exist, hours range from 00 to 23, and minutes and seconds from 00 to 59. Offsets range from -14:00 to +14:00; at 14 hours the minutes must be 00. These checks do not change general literal parsing. Imported or unresolved value shapes remain unknown rather than being inferred from their names.

CodeSeverityReported when
PLAY0482ErrorA generated property is declared outside a command.
PLAY0483ErrorA generated property is not a required, noncollection generatable concept (implicit Uuid uuid or an explicit generation declaration).
PLAY0484ErrorProperty modifiers repeat or are out of order. Write Type optional generated identifier.
PLAY0485ErrorA generated property is supplied as request or form input.
PLAY0486ErrorA command response is malformed, empty, repeated or conditional.
PLAY0487ErrorA response source does not reference one direct command property.
PLAY0488ErrorA response block repeats a field name.
PLAY0489ErrorA response uses a collection or whole read model, or an explicit field type differs from its source’s type, collection shape or optionality.
PLAY0490ErrorA generated fixture repeats a target, names an unknown, nongenerated or identifier property, or supplies an incompatible or nonconcrete value.
PLAY0491ErrorA return expectation is malformed, repeated, incompatible with the response contract, lacks a command action, or accompanies an error or denial.
CodeSeverityReported when
PLAY0492ErrorAn implementation wrapper has an operand, duplicate wrapper, unknown child or nested file child.
PLAY0493ErrorA hint is not one nonblank quoted string, or has children.
PLAY0494ErrorA handler mixes direct/wrapped sources, or a wrapper selects more than one file/inline payload.

These wrapper diagnostics also apply to operation phases. Pending or attached intent is not executable admission.

CodeSeverityReported when
PLAY0495ErrorAn external system declaration is malformed or repeated.
PLAY0496ErrorAn operation declaration or phase is malformed, or supplies event-only metadata.
PLAY0497ErrorA production reference is ambiguous, or a qualified production does not resolve to an explicit operation.
PLAY0498ErrorAn operation name collides with an event or another operation in its owning slice.
PLAY0499ErrorAn operation is produced outside a command.
PLAY0500ErrorAn operation must reference exactly one uniquely declared external system.
PLAY0501ErrorAn operation input mapping is missing, repeated, unknown or incompatible with its declared type.
PLAY0502ErrorAn operation specification step is malformed, unresolved, duplicated, incompatible with its command action or asserts undeclared compensation.
PLAY0508ErrorA numeric preamble has an unknown or malformed spelling, or a numbers exact document nests another numbers directive inside a declaration; only a top-level numbers exact is recognized.
PLAY0509ErrorA physical document repeats its numeric preamble.
PLAY0510ErrorA numeric preamble follows domain, imports or declarations.
PLAY0511ErrorA complete number cannot be represented exactly in the bounded Decimal domain.
PLAY0512ErrorDeclaration-bearing physical documents or marked import barrels disagree on numeric mode.
PLAY0513ErrorSource options or inserted numeric values disagree with their owning mode.

The numeric rows are syntax diagnostics. A valid numbers exact document still cannot bind: PLAY0268 reports that exact numeric mode is not admitted by any supported executable model (ESM) version yet, and unmarked documents keep their existing numeric behavior.

These are syntax diagnostics. A valid system, operation or operation specification still cannot bind: PLAY0268 reports that these constructs are not admitted by any supported executable model (ESM) version yet. Operations do not trigger event destination or payload-identity diagnostics. A valid pending or attached handler remains unsupported independently. Diagnostic repairs for PLAY0471 and PLAY0479 are unchanged.

CodeSeverityReported when
PLAY0516InformationA projection, reducer rule or named reaction trigger uses an event from a later slice, or a command/reaction reads a read model built by a later slice (builder preferred over declaring slice). Reported once per consumer slice and event or read model at its first reference. Reads whose builder’s projections or reducers for the read model being read consume any event produced inside the reader’s child at the reader/builder’s lowest common container are excluded, including from cycle grouping. Projections with a matching variant count, including their shared blocks and variant transitions; unrelated projections and reducers in the same slice do not. Produced events include declarations and command/reaction produces targets, including imported events. A producer in the consumer’s own sub-feature cannot be fixed by reordering. This does not fail --warnaserror.
PLAY0517InformationA sibling group depends on each other’s events or non-feedback read models, so reordering cannot make every dependency flow left to right. Reported once per mutually dependent group, at its earliest backward reference, instead of individual PLAY0516 findings within that group. This does not fail --warnaserror.

See Timeline diagnostics for the ordering root, grouping rules, checked references and C#/MCP repair conditions. PLAY0516 offers verified typed moves or explicit pins before a retained glob where safe; PLAY0517 and own-sub-feature findings have no repair. These findings and repairs do not change executable behavior.

CodeSeverityReported when
PLAY0552WarningAn opted-in container has uncovered counted references into a producer module. One finding per container and producer module, at the container header, with source evidence. If the producers’ shared container is an invalid ancestor target, the finding lists their outermost covering-eligible features instead.
PLAY0553InformationA valid declaration has no counted explicit reference, including provisional ambiguous coverage. Reported at the declaration.
PLAY0556InformationTwo containers declare each other. Reported on each declaring line.
PLAY0554WarningA depends on target is self, an ancestor, a descendant, or does not resolve to a module or feature.
PLAY0555WarningThe same target is declared again on a container, in one file or across files. Resolved aliases count as repeats; unresolved targets compare by text. The first is kept.

An ambiguous target uses PLAY0198, naming the equally near candidates. See Declared dependencies for the sibling and qualified-name rules. Malformed statements are parse errors (PLAY0022 in a module, PLAY0024 in a feature).

CodeCondition
PLAY0503Invalid or duplicate source/stream declaration, including non-scalar types or invalid composite part declarations
PLAY0504Missing or ambiguous source-owned stream, invalid scalar/composite key mapping or literal formatting, or known incompatible command identifier, production destination or key type
PLAY0505Both the route and qualified value-property interpretations are viable; neither is selected
PLAY0506Known scalar or composite part type needs an unsupported portable formatter; bare Int is not supported
PLAY0507Redundant rename-only stored-name pin
PLAY0547Invalid, empty, duplicated, conflicting or misplaced specification route/part block
PLAY0548Specification command occurrence declares routing metadata
PLAY0549Unresolved specification route or missing, unknown, duplicated, mismatched-shape, nonliteral, incompatible or unformattable stream id/part
PLAY0550Missing or incompatible routed source identity, or ambiguous producer fallback without a source identifier
PLAY0551Expected route contradicts its sole producer, the command under test

Valid source/stream authoring selects ESM v8. Executable mappings use direct required, non-collection, non-generated command properties or literals; property paths and handler commands still fail with PLAY0268. Editors and MCP preserve original source evidence; unknown imported type shapes are not guessed. There is no new routing or source-pin quick fix. Existing PLAY0470/PLAY0478 repairs still refuse when executable before/after routing proof is unavailable.

CodeSeverityReported when
PLAY0546WarningSemantic binding applies a policy with a claim under not, directly or through grouping, whose target is an optional path, a command’s subject without an identifier, or a non-string type. An undecidable target evaluates to unknown even under negation; a final unknown policy result denies. Reported at the authorization reference against that command’s properties or query argument. The TypeScript syntax compiler does not perform this semantic check.

See Policies for three-valued evaluation and the distinction between a missing caller claim and a missing comparison target.

CodeSeverityReported when
PLAY0560ErrorAlternatives occur on a trigger other than click, double click or select. Submit and non-item triggers have no structured subject in this version.
PLAY0561ErrorA binding mixes alternatives with plain actions or an opaque where guard.
PLAY0562ErrorA when or otherwise branch has no actions.
PLAY0563ErrorAn interaction uses the labeled-action one-line when … execute … spelling. C# offers a typed block-form repair.
PLAY0564Warning / InformationOpaque where on click, double click or select is deprecated. A strict item condition warns and has a C# typed repair; other text is Information without a repair. Other triggers are unchanged.

Both compilers check these forms. Repairs require individual review (CanFixAll: false) and refuse trailing-comment relocation or comment loss. Conditions reuse PLAY0344–PLAY0348; fallback ordering uses PLAY0343 and missing alternatives uses PLAY0342. See Interactions. Interactions still report PLAY0269 at ESM binding; syntax support is not runtime admission.

CodeSeverityMeaning
PLAY0577ErrorA parameter requires a name and property-line type, without a body or default.
PLAY0578ErrorA case requires an identifier and at most one inline assignment.
PLAY0579ErrorA parameter name is repeated within a table.
PLAY0580ErrorA case name is repeated within a table.
PLAY0581ErrorTables require parameters and at least one case.
PLAY0582ErrorA case omits, repeats or invents a parameter assignment.
PLAY0583ErrorA case value is not concrete or cannot be normalized to its declared parameter type.
PLAY0584ErrorA case reference names no declared table parameter or occurs in an excluded position.
PLAY0585ErrorAn optional parameter feeds a required target.
PLAY0586ErrorA derived specification name collides in its scope.
PLAY0587ErrorThe parameter type is unknown or incompatible with its target type.
PLAY0588WarningA declared parameter is never referenced.
PLAY0589ErrorSingular effective expansion cannot represent a table; use ExpandAll.

See Named case tables.

A retired code stays out of use forever.

CodeRetired inReplacement
PLAY0176v4.25.0Repeated reads without aliases are reported as PLAY0410.
PLAY0686v4.152.0Event rename pins that differ from the name are carried as storedName in ESM v16 (decision 0075); no warning is needed.