windmill-labs/windmill · error · Error
the document must be a mapping (key: value)
Error message
the document must be a mapping (key: value)
What it means
validateShape in FlowYamlEditor.svelte guards against pasting YAML that is not a whole OpenFlow document. The parsed document must be a mapping (not a scalar or array); otherwise `value` assignment and downstream `flowStore.val.value.modules` access would crash the FlowEditor after a success toast.
Source
Thrown at frontend/src/lib/components/flows/header/FlowYamlEditor.svelte:40
let code = $state('')
let initialCode = $state('')
let editor = $state(undefined) as SimpleEditor | undefined
let hasChanges = $derived(code !== initialCode)
function reload() {
code = YAML.stringify(filteredContentForExport(flowStore.val))
initialCode = code
editor?.setCode(code)
}
/** `value` is assigned unconditionally below and `FlowEditor` dereferences
* `flowStore.val.value.modules`, so an OpenFlow document missing it takes the
* whole editor down mid-render — after the toast has already claimed success.
* Reject it up front instead. */
function validateShape(parsed: unknown) {
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
throw new Error('the document must be a mapping (key: value)')
}
const value = (parsed as Record<string, unknown>).value
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
throw new Error("missing 'value' - paste a whole OpenFlow document, not just its value")
}
if (!Array.isArray((value as Record<string, unknown>).modules)) {
throw new Error("'value.modules' must be a list")
}
}
function validateGroups(groups: { start_id: string; end_id: string }[] | undefined) {
if (!groups) return
const seen = new Set<string>()
for (const g of groups) {
const key = `${g.start_id}:${g.end_id}`
if (seen.has(key)) {
throw new Error(`Duplicate group: '${g.start_id}' → '${g.end_id}'`)
}View on GitHub (pinned to e474e8803c)
Solutions
- Paste the complete OpenFlow document including the top-level `value` key with a `modules` array
- Wrap scalar/list YAML under a mapping, e.g. `value:\n modules: [...]`
- Use the flow's Export function to get a correctly shaped document and edit that
Example fix
// before
- id: a
value: {}
// after
value:
modules:
- id: a
value: {} Defensive patterns
Strategy: validation
Validate before calling
const doc = YAML.parse(text)
if (typeof doc !== 'object' || doc === null || Array.isArray(doc)) throw new Error('Paste a whole OpenFlow mapping, not a list or scalar')
if (!doc.value || Array.isArray(doc.value) || !Array.isArray(doc.value.modules)) throw new Error("Missing value.modules") Type guard
function isOpenFlowDoc(v: unknown): v is { value: { modules: unknown[] } } {
return typeof v === 'object' && v !== null && !Array.isArray(v) &&
typeof (v as any).value === 'object' && (v as any).value !== null &&
Array.isArray((v as any).value.modules)
} Try / catch
try { apply(text) } catch (e) { sendUserToast(e.message, true) } Prevention
- Export the flow from the UI and edit that document as a template
- Never paste partial subtrees (modules-only) into the YAML editor
- Run validateShape before any store write and show the message in the editor gutter
When it happens
Trigger: The user pastes YAML that parses to a scalar or a list (e.g. just the modules list, or a single key line) into the YAML editor and clicks apply; validateShape runs before storing and rejects it.
Common situations: Copying only the `value:` subtree instead of the full OpenFlow document; pasting a flow snippet from docs that is an array of steps; YAML with top-level sequence syntax (dashes).
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}
- missing 'value' - paste a whole OpenFlow document, not just
- 'value.modules' must be a list
- Duplicate group: '${g.start_id}' → '${g.end_id}'
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/77dedb831c39a0c6.
Report an issue: GitHub.