{"record":{"id":"200cf2359a568813","repo":"windmill-labs/windmill","slug":"draft-path-has-no-content-language","errorCode":null,"errorMessage":"draft ${path} has no content/language","messagePattern":"draft (.+?) has no content/language","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/routes/(root)/(logged)/pipeline/[folder]/+page.svelte","lineNumber":1535,"sourceCode":"\t// mixed chain. Drafts run as previews of their local content; deployed\n\t// scripts run their *saved* version (an open editor buffer with unsaved\n\t// edits is not picked up — same as production dispatch).\n\tasync function launchCascadeScript(path: string): Promise<string> {\n\t\tif (!$workspaceStore) throw new Error('no workspace')\n\t\t// Only run draft content when the displayed graph actually includes\n\t\t// drafts (same condition as `displayGraph`). Otherwise — View mode with\n\t\t// drafts hidden — a bounded run must execute the *deployed* scripts the\n\t\t// user is looking at, not preview jobs from hidden local drafts.\n\t\t// Default a script's run args to its schedule's stored payload (the only\n\t\t// trigger with static args — see resolveScheduleArgs), then let a\n\t\t// data-upload entry's staged file override. runWholePipeline already\n\t\t// refused to start unless every data-upload entry is staged, so this is\n\t\t// always the intended input.\n\t\tconst staged = { ...(scheduleArgsByPath[path] ?? {}), ...(dataUploadArgs[path]?.args ?? {}) }\n\t\tconst draft = mode === 'edit' || includeDrafts ? pe.drafts.get(path) : undefined\n\t\tif (draft) {\n\t\t\tif (!draft.script.content || !draft.script.language) {\n\t\t\t\tthrow new Error(`draft ${path} has no content/language`)\n\t\t\t}\n\t\t\treturn await JobService.runScriptPreview({\n\t\t\t\tworkspace: $workspaceStore,\n\t\t\t\trequestBody: {\n\t\t\t\t\tcontent: draft.script.content,\n\t\t\t\t\tlanguage: draft.script.language,\n\t\t\t\t\tpath,\n\t\t\t\t\targs: { ...staged, _wmill_skip_asset_dispatch: true }\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t\treturn await JobService.runScriptByPath({\n\t\t\tworkspace: $workspaceStore,\n\t\t\tpath,\n\t\t\trequestBody: { ...staged, _wmill_skip_asset_dispatch: true }\n\t\t})\n\t}\n\t// Poll a launched cascade job to a terminal state. Modest fixed cadence —","sourceCodeStart":1517,"sourceCodeEnd":1553,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/routes/(root)/(logged)/pipeline/[folder]/+page.svelte#L1517-L1553","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nawait runNode(path)\n// after\nconst d = pe.drafts.get(path)\nif (d && d.script.content && d.script.language) await runNode(path)","handlingStrategy":"validation","validationCode":"const d = pe.drafts.get(path);\nif (d && (!d.script.content || !d.script.language)) {\n  throw new Error(`draft ${path} has no content/language`);\n}","typeGuard":"function isRunnableDraft(d: unknown): d is { script: { content: string; language: string } } {\n  const x = d as any;\n  return !!x?.script?.content && !!x?.script?.language;\n}","tryCatchPattern":"try { await runNode(path); } catch (e) {\n  if (e.message.includes('has no content/language')) { openDraftEditor(path); }\n  else throw e;\n}","preventionTips":["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"],"tags":["pipeline","draft","state","validation"],"backgroundTag":"invalid-draft-state","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}