Diagnostics
Every message runtime model validate can produce, by code.
Codes are permanent. Retiring a check retires its number with it, and a number is never reused — so a code in a script, a ticket or a runbook means the same thing forever.
A diagnostic names the file, the path within it, what is wrong, and — wherever there is an answer — what to write instead. If one of these is ever unclear, that is worth reporting: the premise of the product is that models are written by people and language models working from the schema and these messages.
$ runtime model validate myapp
error[M203]: `precision` is not a parameter of type `string`
--> modules/sales/domain.yaml (entities[0].attributes[1])
help: remove it, or change the type to `decimal`
Parse
The file could not be read as a model at all: it is missing, it is not YAML, or it does not match the schema.
| Code | Meaning |
|---|---|
M001 | A file the bundle requires is not there. |
M002 | The file is not well-formed YAML. |
M003 | The YAML is well-formed but does not match the schema. |
M004 | schemaVersion is a version this runtime does not know. |
Resolve
The file parsed, and something it names does not exist.
| Code | Meaning |
|---|---|
M101 | app.yaml lists a module with no directory. |
M102 | A file’s module: disagrees with the directory it is in. |
M103 | An association targets an entity that does not exist. |
M104 | An index or access rule names an attribute that does not exist. |
M105 | A user role grants a module role that does not exist. |
M106 | roleMapping or anonymousRole names a user role that does not exist. |
M107 | A flow names a script file the bundle does not contain. |
M108 | A flow’s allow names a role this module does not define. |
M109 | A metric’s label names an attribute the entity does not have. |
Check
Everything named exists, and something about it does not make sense.
| Code | Meaning |
|---|---|
M201 | A name does not follow the casing convention for its kind. |
M202 | Two things in the same scope share a name. |
M203 | A type-specific parameter was given for a type that has no such parameter, such as precision on a string. |
M204 | A type-specific parameter that is required for this type is missing, such as a decimal without precision. |
M205 | A parameter is present but its value cannot be satisfied. |
M206 | A default cannot be represented in the attribute’s type. |
M207 | An index lists no attributes. |
M208 | previousName is the same as name, which declares nothing. |
M209 | Two elements claim the same previousName. |
M210 | A metric label names an attribute whose type is unbounded. |
M211 | A metric name does not follow the OpenTelemetry naming convention. |
M212 | A metric’s when uses something a committed row cannot answer. |
Constraints
A constraint or condition expression is wrong.
| Code | Meaning |
|---|---|
M301 | A constraint expression does not parse. |
M302 | A path in a constraint does not resolve against the domain model. |
M303 | A comparison puts two incompatible types either side of an operator. |
Warnings
Legal, and nearly always unfinished. These do not stop a model from loading.
| Code | Meaning |
|---|---|
M901 | An entity with no attributes. |
M902 | A role grants access to an entity in a different module. |
M903 | A flow no role may invoke. |
M904 | A metric no operation triggers. |
Severity
M0xx through M3xx are errors: the model does not load.
M9xx are warnings: the model loads and runs. They exist because the thing they
describe is legal and almost always a mistake in progress — a flow no role can
invoke will never be called, and a metric nothing triggers will read zero
forever, which looks exactly like the thing never happening.
The three passes
Which pass reports a problem determines how good the message can be, which is why they are separate:
- Parse — is this YAML, and does it match the schema? Nothing is known about the model yet, so the message is about syntax and shape.
- Resolve — does
sales.Customerexist, does that attribute exist on it? Names can now be checked, and a near-miss gets a suggestion. - Check — is this expression well-typed, is this parameter applicable, does this default fit? The whole model is known, so the message can be specific.
A failure in an early pass stops the later ones for that file, because a message derived from a half-understood model is worse than no message.
Keeping this page honest
The table above is generated from the runtime’s Code enum. Codes are added
rarely and never removed, so it drifts slowly — but it does drift. To check:
grep -oE '"M[0-9]{3}"' ../runtime/crates/runtime-model/src/diagnostic.rs \
| tr -d '"' | sort -u > /tmp/actual
grep -oE 'M[0-9]{3}' src/reference/diagnostics.md | sort -u > /tmp/documented
diff /tmp/actual /tmp/documented
A code in the runtime and not here is a message somebody will meet with nothing to look up.