Validating a Config
sovrium validate decodes a config file against AppSchema — the same schema the server decodes at boot — and reports every problem it finds. It touches no database, binds no port, and needs no environment, which makes it the cheapest place to catch a broken config.
sovrium validate app.yaml
sovrium validate config.json
sovrium validate app.tsIt accepts .json, .yaml, .yml and .ts, and resolves every $ref include before checking anything — so a config split across twenty files is validated as the one object it becomes.
What success looks like
Valid configuration: my-appExit code 0. This is the same decode the server performs at startup, in both directions: a config that validates will boot, and a config this rejects is one sovrium start and sovrium build refuse too.
What failure looks like
Problems print under a single Error: Validation failed. header, and exit 1. An unrecognised property is named, located, and answered with the keys that node does accept:
Error: Validation failed.
Unknown property 'tag' on component type 'text'
at pages[0].components[0]
Accepted here: type, children, props, content, interactions, responsive,
visibility, i18n, session, element, requiredWhen the spelling is a near miss, the report says so — Did you mean 'element'? — but only when the correction is actually derivable. A suggestion that is always produced would send you to the wrong property, so a name with no near neighbour gets the accepted-key list and nothing more.
Structural problems that are not a stray key — a missing name, a number where a string belongs — print as the decoder's indented tree instead. Read that one from the bottom: it walks down through the schema before it reaches your config, so the top is machinery and the last lines are the finding.
One property per run. A config with three typos reports one of them. Fix it, run again.
The four classes of error
| Class | Example | Caught by |
|---|---|---|
| Structural | name missing; a number given a string |
The AppSchema decode |
| Unrecognised property | tabels: instead of tables: |
Excess-property rejection |
| Unknown field type | type: web-site on a table field |
The post-decode sweep |
| Unresolvable field | rowColorField: statuss on a table with no such field |
Cross-field checks |
The second is the contract worth stating in full, because it governs the whole file:
Every property in your config is either understood and honoured, or reported as an error. Nothing is silently ignored. sovrium validate, sovrium start and sovrium build all enforce this, identically — they run the same decoder.
One deliberate exception: props. It is an open passthrough for HTML and ARIA attributes, forwarded to the browser without interpretation, so Sovrium cannot know which keys are meaningful there. A typo inside props is not caught. The same key one level up is.
Before this contract existed, an unrecognised key was dropped and the server started anyway — so tag: 'h1' on a text component (the property is spelled element) rendered a plain <p> with no error anywhere. The only evidence was the feature not being there.
That exception is also the escape hatch. An attribute Sovrium has no schema property for belongs under props:
components:
- type: text
content: Hello
props:
data-analytics-id: hero # forwarded verbatimThe third runs after the decode, and prints plainly rather than as a tree:
Error: Validation failed.
Unknown field type "web-site" in field "website"With a multi-file config the finding is attributed to the partial it came from — companies.yaml: Unknown field type ....
Single-word field types are not flagged. The sweep only reports a type it cannot recognise and that contains a - or _. A bare word like colour is treated as a plausible alias, passes validation, and fails later during SQL generation. Check spellings against Field Types Overview rather than relying on this sweep alone.
The fourth reads your config against itself: a component names a field, and the table it is bound to has to declare it.
Error: Validation failed.
rowColorField: field 'statuss' not found in table 'orders'. Available: id, customer, statusThis one changes what your app does, not only what the validator says. A columns[].field, a chart series[].field, a kanban colorField or a form fields[].field naming a column that is not there used to render nothing and report nothing — indistinguishable from a column whose rows happen to be empty. Listing a view type without the config that builds it behaved the same way: views: ['kanban'] with no kanbanGroupBy drew a tab that did nothing when clicked. Both are now refused by all three commands, so the mistake surfaces at your desk instead of shipping as a feature that looks deliberate.
System columns (id, the timestamps, the authorship columns) always resolve — they exist without appearing in fields[]. A component bound to a system source rather than a table is skipped, since its columns describe an endpoint's response rather than a declared table.
Exit codes
| Exit code | Meaning |
|---|---|
0 |
Config is valid |
1 |
Config is invalid (decode error, unknown field type, missing file) |
Everything failed is 1, so gating a pipeline is a single line:
sovrium validate app.yaml || exit 1Run it before the deploy step. It is the last point where a bad config costs you seconds instead of a rollback.
Validating from inside a config
To check a config from a running app rather than from a shell — a webhook that receives a submitted config, a scheduled audit — use the sovrium:validateConfig automation action. It runs this same decoder, with no side effects and no boot, and exposes {{steps.<name>.valid}} and {{steps.<name>.errors}}:
automations:
- name: check-submitted-config
trigger:
type: webhook
method: POST
actions:
- name: check
type: sovrium
operator: validateConfig
props:
config: '{{trigger.data.config}}'
format: autoThere is no looser in-process alternative, by design: a second validator that tolerated what this one rejects would mean a config could pass one gate and fail the other. The candidate is also read verbatim — a {{...}} or $env.X inside the submitted config is validated as literal text, never resolved — so the verdict describes what you passed rather than a rewritten copy of it. Full details on Validation & Schema Generation and Automation Actions.
Related Pages
- Project Commands —
sovrium validatealongsideinit,build,schema. - Validation & Schema Generation —
sovrium validateandsovrium schemaside by side. - Editor Setup — catching structural errors as you type.
- Multi-File Configs — how
$reffiles are attributed in errors. - Troubleshooting — the other errors a boot can print.
Last updated September 1, 2026
This documentation was written with AI, so errors or outdated content are possible. Sovrium is in beta. Contributions and corrections are welcome.