windmill-labs/windmill · error
Top-level YAML must be a mapping
Error message
Top-level YAML must be a mapping
What it means
apply() in the raw-app YAML editor parses the textarea contents with YAML.parse and requires the top-level node to be a plain object (mapping). If the YAML parses to a scalar, array, or null, it throws this error instead of applying a partial update, because the update extraction logic can only read keys (summary, files, ...) off a mapping.
Source
Thrown at frontend/src/lib/components/raw_apps/RawAppYamlEditor.svelte:55
summary,
files: files ?? {},
runnables,
data
}
code = YAML.stringify(snapshot)
initialCode = code
editor?.setCode(code)
}
function isPlainObject(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null && !Array.isArray(value)
}
function apply() {
try {
const parsed = YAML.parse(code)
if (!isPlainObject(parsed)) {
throw new Error('Top-level YAML must be a mapping')
}
const update: RawAppYamlUpdate = {}
if (typeof parsed.summary === 'string') {
update.summary = parsed.summary
}
if (isPlainObject(parsed.files)) {
update.files = parsed.files as Record<string, string>
}
if (isPlainObject(parsed.runnables)) {
update.runnables = parsed.runnables as Record<string, Runnable>
}
if (isPlainObject(parsed.data)) {
update.data = parsed.data as unknown as RawAppData
}
onApply(update)
initialCode = code
sendUserToast('Changes applied')
} catch (e) {View on GitHub (pinned to e474e8803c)
Solutions
- Ensure the YAML root is a mapping like 'summary: ...' with 'files:' as a nested mapping, not a list or scalar
- Do not apply an empty editor; restore valid YAML or reload the current app definition
- Validate locally with YAML.parse and isPlainObject before clicking apply
Example fix
// before - app.ts // after summary: My app files: app.ts: <content>
Defensive patterns
Strategy: validation
Validate before calling
import YAML from 'yaml';
const parsed = YAML.parse(code);
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
throw new Error('Top-level YAML must be a mapping');
} Type guard
function isPlainObject(v: unknown): v is Record<string, unknown> {
return typeof v === 'object' && v !== null && !Array.isArray(v);
} Try / catch
try { apply(); } catch (e) {
if (e.message === 'Top-level YAML must be a mapping') { showYamlSyntaxHint(); }
else throw e;
} Prevention
- Always author raw-app YAML with a mapping root (key: value), never a bare list or scalar
- Lint/paste-validate YAML before clicking apply
- Never apply an empty editor
When it happens
Trigger: Clicking apply in the RawAppYamlEditor with YAML whose root is a list (e.g. '- a\n- b'), a bare scalar (e.g. 'hello'), an empty document (parses to null), or multiple documents/typo leading to a non-mapping root.
Common situations: Pasting a files-array snippet instead of a mapping; clearing the editor and hitting apply; copy-pasting YAML with a leading '-' making it a sequence.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Document must be a string
- Unsupported trigger kind: ${target.triggerKind}
- the document must be a mapping (key: value)
- missing 'value' - paste a whole OpenFlow document, not just
- 'value.modules' must be a list
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/b114af640d35941a.
Report an issue: GitHub.