kestra-io/kestra · error · TourSceneError
onboarding.tour.errors.save_flow
Error message
onboarding.tour.errors.save_flow
What it means
Thrown by the onboarding tour when persisting the tour flow is blocked by validation. applySource writes the YAML source, calls flowStore.saveAll(), and if the outcome is 'blocked' it raises TourSceneError with key 'onboarding.tour.errors.save_flow' and a reason built from joined flow errors. 'blocked' means the store detected schema/validation errors and refused to save.
Source
Thrown at ui/src/components/onboarding/tour/useTourActions.ts:240
await FlowsAPI.createFlow({
body: source,
showMessageOnError: false,
} as Parameters<typeof FlowsAPI.createFlow>[0])
await flowStore.loadFlow({namespace: TOUR_NAMESPACE, id: TOUR_FLOW_ID})
}
await flowStore.initYamlSource()
return flowStore.flow
}
const applySource = async (source: string) => {
if (route.name !== "flows/create") {
return saveSource(source)
}
await writeSource(source)
const outcome = await flowStore.saveAll()
if (outcome === "blocked") {
throw new TourSceneError("onboarding.tour.errors.save_flow", {
reason: flowStore.flowErrors?.join(" ") ?? "",
})
}
await openFlowEditor()
return flowStore.flow
}
const openEditorWith = async (source: string) => {
await saveSource(source)
await openFlowEditor()
await flowStore.initYamlSource()
}
const latestRevision = async (id: string = TOUR_FLOW_ID) => {
const flow = await flowStore.loadFlow({namespace: TOUR_NAMESPACE, id, store: false})
return flow?.revision as number | undefined
}
View on GitHub (pinned to 823fada927)
Solutions
- Inspect flowStore.flowErrors after the failure — the joined strings name the exact validation problems.
- Re-apply the canonical tour flow source for your Kestra version (the tour payload is version-pinned).
- Confirm all plugins referenced by the tour flow are installed and loaded.
- If a Kestra upgrade broke the bundled tour YAML, update the onboarding tour payload to match the new schema.
Defensive patterns
Strategy: validation
Validate before calling
// Validate before save
const outcome = await flowStore.saveAll();
if (outcome === 'blocked') {
// do not throw yet; show errors and let the user fix
surfaceFlowErrors(flowStore.flowErrors);
} Try / catch
try {
const outcome = await flowStore.saveAll();
if (outcome === 'blocked') {
throw new TourSceneError('onboarding.tour.errors.save_flow', {reason: flowStore.flowErrors?.join(' ') ?? ''});
}
} catch (e) {
if (e instanceof TourSceneError) { showFlowErrorDialog(e.reason); return; }
throw e;
} Prevention
- Pre-validate the tour flow YAML against the schema before the save step.
- Pin the tour payload to the matching Kestra version so schema drift does not block saves.
- Expose flowErrors to the user so they can self-correct.
When it happens
Trigger: In the tour, route is 'flows/create', writeSource(source) succeeds, flowStore.saveAll() returns 'blocked' (flowErrors non-empty), and TourSceneError is thrown with reason = flowStore.flowErrors.join(' ').
Common situations: The injected tour YAML got corrupted by an editor plugin or stray edit, a plugin task in the tour flow is missing (plugin not installed), the flow references an unknown property, or a Kestra version change made the bundled tour flow invalid.
Related errors
- onboarding.tour.errors.test_event
- onboarding.tour.errors.no_execution_to_replay
- Cannot run the invalid flow '%s'.'%s': %s
AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14).
Data as JSON: /api/errors/b36964f26ab502cc.
Report an issue: GitHub.