windmill-labs/windmill · error
draft ${path} has no content/language
Error message
draft ${path} has no content/language What it means
When running a pipeline node from the editor, drafts are preferred as the runnable input. If the editor mode expects drafts (edit mode or drafts included) and a draft exists for the path but its script is missing content or language, the page throws this error rather than calling runScriptPreview with an invalid empty request.
Source
Thrown at frontend/src/routes/(root)/(logged)/pipeline/[folder]/+page.svelte:1535
// mixed chain. Drafts run as previews of their local content; deployed
// scripts run their *saved* version (an open editor buffer with unsaved
// edits is not picked up — same as production dispatch).
async function launchCascadeScript(path: string): Promise<string> {
if (!$workspaceStore) throw new Error('no workspace')
// Only run draft content when the displayed graph actually includes
// drafts (same condition as `displayGraph`). Otherwise — View mode with
// drafts hidden — a bounded run must execute the *deployed* scripts the
// user is looking at, not preview jobs from hidden local drafts.
// Default a script's run args to its schedule's stored payload (the only
// trigger with static args — see resolveScheduleArgs), then let a
// data-upload entry's staged file override. runWholePipeline already
// refused to start unless every data-upload entry is staged, so this is
// always the intended input.
const staged = { ...(scheduleArgsByPath[path] ?? {}), ...(dataUploadArgs[path]?.args ?? {}) }
const draft = mode === 'edit' || includeDrafts ? pe.drafts.get(path) : undefined
if (draft) {
if (!draft.script.content || !draft.script.language) {
throw new Error(`draft ${path} has no content/language`)
}
return await JobService.runScriptPreview({
workspace: $workspaceStore,
requestBody: {
content: draft.script.content,
language: draft.script.language,
path,
args: { ...staged, _wmill_skip_asset_dispatch: true }
}
})
}
return await JobService.runScriptByPath({
workspace: $workspaceStore,
path,
requestBody: { ...staged, _wmill_skip_asset_dispatch: true }
})
}
// Poll a launched cascade job to a terminal state. Modest fixed cadence —View on GitHub (pinned to e474e8803c)
Solutions
- Open the draft and save actual script content (and ensure language is set) before running
- Delete the empty/stale draft and re-create it from the step
- Run in non-edit mode without drafts so the page falls back to the deployed script instead of the draft
- Guard before run: check draft.script.content && draft.script.language
Example fix
// before await runNode(path) // after const d = pe.drafts.get(path) if (d && d.script.content && d.script.language) await runNode(path)
Defensive patterns
Strategy: validation
Validate before calling
const d = pe.drafts.get(path);
if (d && (!d.script.content || !d.script.language)) {
throw new Error(`draft ${path} has no content/language`);
} Type guard
function isRunnableDraft(d: unknown): d is { script: { content: string; language: string } } {
const x = d as any;
return !!x?.script?.content && !!x?.script?.language;
} Try / catch
try { await runNode(path); } catch (e) {
if (e.message.includes('has no content/language')) { openDraftEditor(path); }
else throw e;
} Prevention
- Never create placeholder drafts without content before enabling run
- Save drafts with both content and language set before running
- Fall back to the deployed script when the draft is incomplete
- Guard runScriptPreview calls with a content/language check
When it happens
Trigger: Clicking run on a script node whose staged draft has empty script.content or missing draft.script.language — e.g. a freshly created draft never saved with content, or a draft loaded incompletely.
Common situations: Creating an empty draft then hitting run; a draft synced from a failed load; includeDrafts enabled and a placeholder draft for a new path present; data-upload staging pointing at an unpopulated draft.
Related errors
- No local file for ${scriptPath} to infer its S3Object parame
- Pipeline node content must declare the pipeline annotation o
- result.substring(__RESULT_ERR_PREFIX.length)
- Invalid migration name '${name}': use only letters, digits,
- Unknown workspace dependencies file format: ${path}. Valid f
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/200cf2359a568813.
Report an issue: GitHub.