Skip to content

What the loader refuses and warns about

When Realm reads a workflow.yaml, it either accepts the file, accepts it with warnings, or refuses it. This page describes the three outcomes as realm workflow validate prints them, lists all 18 warning codes, and gives the machine-readable form of the result.

realm workflow register applies the same checks before it stores anything.

Accepted. One line, and exit code 0:

Valid: w v1 (1 step)

Accepted with warnings. Each warning on a line that starts with ⚠, then the same Valid line. The exit code is 0:

⚠ Step 'fetch': 'retry.on_timeout: true' has no effect with an effective 'max_attempts' of 1 — there is no second attempt to retry into.
Valid: w v1 (1 step)

Refused. One or more errors, and exit code 1. A single error is printed on one line:

Invalid workflow: Step 'a': missing required field 'description' (step at line 5)

Several errors are listed together, so that one pass shows them all:

Invalid workflow — 2 errors:
Step 'fetch': invalid execution value 'manual'; must be 'auto', 'agent', 'guard', or 'finalizer' (step at line 5)
Step 'other': missing required field 'description' (step at line 8)

Three other forms of refusal:

When Printed
A warning that counts as an error Invalid: 1 warning, 1 escalated to an error by policy: UNKNOWN_STEP_KEY 'colour'
The file is not valid YAML Invalid: YAML parse error: bad indentation of a mapping entry (7:14), then the lines around the place
The file cannot be read Invalid: Failed to read workflow file: ENOENT: no such file or directory, open 'nowhere/workflow.yaml'

A line that starts with ℹ is neither a warning nor an error. It is a note, such as how many steps could use strict output. Set REALM_NO_NUDGE=1 to leave these notes out.

Messages end with the place in the file:

Form Points at
(line 8) The line of the key the message is about.
(step at line 5) The line where the step begins.
(7:14) In a YAML error, the line and the column.

A message has no line when the place could not be found exactly.

The loader has 18 warning codes. Two of them count as errors: an unknown key at the top of the file or on a step makes validate and register fail. The others are advice, and the file is accepted.

Code Counts as Printed when
UNKNOWN_WORKFLOW_KEY Error The top of the file has a field Realm does not know.
UNKNOWN_STEP_KEY Error A step has a field Realm does not know.
UNKNOWN_RETRY_KEY Warning A retry block has a key that is not one of its six.
UNKNOWN_GATE_KEY Warning A gate block has a key that is not one of its nine.
UNKNOWN_VALIDATION_EXHAUSTION_KEY Warning A validation_exhaustion block has a key that is not one of its three.
UNKNOWN_CREATE_WORKFLOW_KEY Warning An assistant sent create_workflow a field it does not take. Not printed for files.
RETRY_NO_TIMEOUT Warning A step has retry and no timeout_seconds.
ON_TIMEOUT_SINGLE_ATTEMPT Warning retry.on_timeout is set and the step is tried only once.
TOTAL_TIMEOUT_BELOW_ATTEMPT Warning retry.total_timeout_seconds is below timeout_seconds.
TOTAL_TIMEOUT_NON_AUTO Warning retry.total_timeout_seconds is on a step that is not an auto step.
RETRY_INERT_NON_AUTO Warning retry is on an agent or guard step, where it does nothing.
IDEMPOTENT_INERT_IN_FINALIZER Warning A step says idempotent: true in a workflow that has a finalizer.
DUAL_SCHEMA_DECLARED Warning A step has both input_schema and output_schema.
DEAD_GATE_CONFIG Warning A gate setting can have no effect.
DEAD_VALIDATION_EXHAUSTION_CONFIG Warning default_output is set without mode: default.
SCHEMA_STRICT_ADVISORY Warning A schema compiles, and uses a list of types or a check without its type.
EXTENSION_SENTINEL Warning A secret named in realm.yaml could not be found, so the check ran with placeholders.
REALM_RELEASE_LINE_MISMATCH Warning The @sensigo/realm the project’s code imports is not the version the command runs. Added in 0.46.0.

An unknown key is reported with its line, and with the nearest known key when there is one:

⚠ step 'fetch': unknown key 'depend_on' (line 8) — ignored (did you mean 'depends_on'?)
Invalid: 1 warning, 1 escalated to an error by policy: UNKNOWN_STEP_KEY 'depend_on'

Fields that start with x- at the top of the file are not unknown keys. See Top-level fields.

The pages for each block show the full text of each warning: Retry and timeouts, Gates, Agent-step controls and JSON Schema blocks.

With --strict, validate and register treat every warning as a failure. The file is still described as valid, and the exit code is 1:

Valid: w v1 (1 step) — 1 warning; failing due to --strict

register --strict stores nothing when it fails, and says so: Error: 'strictreg' v1 has 1 warning; refusing to register due to --strict.

REALM_RELEASE_LINE_MISMATCH counts as a warning here too: with --strict, validate and register fail when the @sensigo/realm your code imports is not the version the command runs. Without --strict the workflow is still registered. This was added in 0.46.0.

By default, validate prints one line about steps that could use structured_output: strict. With --explain it prints one line for each such step:

ℹ Step 'classify': eligible for structured_output: strict — add 'structured_output: strict' to opt in.

With --json, validate prints one JSON object and nothing else on standard output. The exit code is the same as without it.

{
"valid": false,
"mode": "file",
"path": "./",
"workflow_id": "w",
"loader_version": "0.46.0",
"schema_version": null,
"error_count": 1,
"warning_count": 1,
"strict": { "requested": false, "failed": false },
"diagnostics": [
{
"code": "UNKNOWN_STEP_KEY",
"severity": "error",
"message": "step 'fetch': unknown key 'depend_on' (line 8) — ignored (did you mean 'depends_on'?)",
"scope": "step",
"key": "depend_on",
"step": "fetch",
"did_you_mean": "depends_on",
"line": 8,
"column": 5,
"endLine": 8,
"endColumn": 14
}
],
"errors": ["Invalid: 1 warning, 1 escalated to an error by policy: UNKNOWN_STEP_KEY 'depend_on'"],
"checks_not_run": [],
"extension_keys": []
}
Field Holds
valid Whether the file was accepted.
mode file, or registered when --registered was used.
workflow_id The workflow’s id, or null when the file could not be read that far.
loader_version The version of Realm that did the check.
error_count, warning_count How many of each.
strict Whether --strict was given, and whether it turned an accepted file into a failure.
diagnostics One entry for each warning: code, severity, message, scope, and where known step, key, did_you_mean, and the position. A REALM_RELEASE_LINE_MISMATCH entry comes first and also carries release_line: { project: { version, path, installed_by }, engine: { version, path } }, where installed_by is project for the project’s own copy or the package that installed it (for example @sensigo/realm-cli), and a path has no trailing separator (added in 0.46.0).
errors The error lines, as text.
checks_not_run Checks that were left out, each with the reason. Used with --registered.
extension_keys The x- fields found at the top of the file.

In a position, line and column count from 1, and endColumn is one past the last character.

An error that is not a warning, such as a missing required field, appears in errors and has no entry in diagnostics. The warnings about secrets that could not be found are printed on standard error and are not in diagnostics.