windmill-labs/windmill · error · Error
Failed to parse or apply JSON: ${error instanceof Error ? er
Error message
Failed to parse or apply JSON: ${error instanceof Error ? error.message : String(error)} What it means
This wraps any failure raised while parsing and applying a JSON-based flow edit in FlowAIChat.svelte. The original error's message is appended so the developer sees the underlying cause (JSON.parse failure, schema mismatch, or an error thrown by the apply logic).
Source
Thrown at frontend/src/lib/components/copilot/chat/flow/FlowAIChat.svelte:245
}
}
const result = applyFlowJsonUpdate(flowStore.val, inlineScriptSession, {
modules,
schema,
preprocessorModule,
failureModule,
groups,
notes,
settings
})
// Refresh the state store to update UI
refreshStateStore(flowStore)
await acceptPendingFlowEditsIfEnabled(true)
return result
} catch (error) {
throw new Error(
`Failed to parse or apply JSON: ${error instanceof Error ? error.message : String(error)}`
)
}
}
}
$effect(() => {
if (
!aiChatManager.autoAcceptEditsActive &&
$currentEditor?.type === 'script' &&
selectedId &&
diffManager?.moduleActions[selectedId]?.pending &&
$currentEditor.editor.getAiChatEditorHandler()
) {
const moduleLastSnapshot = diffManager.beforeFlow
? (findModuleInFlow(diffManager.beforeFlow.value, selectedId) ?? undefined)
: undefined
const content =View on GitHub (pinned to e474e8803c)
Solutions
- Read the wrapped inner message to identify the real failure (parse vs apply)
- Retry the generation asking the model for strict raw JSON without code fences
- Validate the JSON against the flow schema before applying; add a pre-parse sanitization step
Example fix
// before
throw new Error(`Failed to parse or apply JSON: ${error instanceof Error ? error.message : String(error)}`)
// after
const raw = text.replace(/^```(?:json)?\n?|\n```$/g, '')
let parsed
try { parsed = JSON.parse(raw) } catch (e) {
throw new Error(`Invalid JSON from model: ${e.message}`)
} Defensive patterns
Strategy: try-catch
Validate before calling
let parsed
try { parsed = JSON.parse(rawText) } catch (e) { throw new Error(`Model returned invalid JSON: ${e.message}`) }
if (typeof parsed !== 'object' || parsed === null) throw new Error('Model JSON is not an object') Type guard
function isJsonObject(v: unknown): v is Record<string, unknown> { return typeof v === 'object' && v !== null && !Array.isArray(v) } Try / catch
try { result = applyFlowJson(raw) } catch (error) { console.error('flow json apply failed', error); sendUserToast(`Failed to parse or apply JSON: ${error.message}`, true) } Prevention
- Strip markdown code fences before JSON.parse
- Request strict JSON output from the model
- Cap flow size to avoid truncated generations
When it happens
Trigger: The AI tool returns JSON that fails to parse (truncated/malformed output), or the parsed document fails during application (invalid flow structure, store update failure) inside the try block ending at `refreshStateStore(flowStore)` / `acceptPendingFlowEditsIfEnabled(true)`.
Common situations: Model emits markdown-fenced or truncated JSON; large flows hit output token limits; the apply step references modules/paths absent from the current flow.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Invalid JSON for ${field}: ${errorMessage}
- Invalid JSON after replacement: ${message}
- Invalid JSON for ${field}: ${message}${hint}
- Invalid JSON after replacement: ${message}
- {} is not valid json: {}
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/bd8e23bd29621eb6.
Report an issue: GitHub.