windmill-labs/windmill · error · Error
Draft script "${moduleValue.path}" is missing content or lan
Error message
Draft script "${moduleValue.path}" is missing content or language. What it means
When resolving a flow module's script content, a draft script for the module's path is checked first. If the draft exists but has no string content or no language, the tool throws instead of silently falling back, because the draft — not the deployed script — is the source of truth the model is editing. Deployed scripts are only read when no draft exists.
Source
Thrown at frontend/src/lib/components/copilot/chat/global/core.ts:5340
)
}
function normalizeTestRunArgs(args: Record<string, any> | null | undefined): Record<string, any> {
return args ?? {}
}
function flowDraftValueForPreview(flowDraft: FlowDraftValue): FlowValue {
return flowDraftAsEditableInput(flowDraft).value
}
async function loadScriptForFlowStep(
moduleValue: { path: string; hash?: string },
workspace: string
): Promise<{ content: string; language: ScriptLang }> {
const draft = await getGlobalDraft(workspace, 'script', moduleValue.path)
if (draft) {
if (typeof draft.value !== 'string' || !draft.language) {
throw new Error(`Draft script "${moduleValue.path}" is missing content or language.`)
}
return { content: draft.value, language: draft.language }
}
const script = moduleValue.hash
? await ScriptService.getScriptByHash({ workspace, hash: moduleValue.hash })
: await ScriptService.getScriptByPath({ workspace, path: moduleValue.path })
return { content: script.content, language: script.language }
}
async function loadDraftFlowPreviewValue(
path: string,
workspace: string
): Promise<FlowValue | undefined> {
if (!(await getGlobalDraft(workspace, 'flow', path))) {
return undefined
}
const nestedFlow = await loadFlowDraftValue(path, workspace)View on GitHub (pinned to e474e8803c)
Solutions
- Complete the draft with write_script (content + language) for that path, then retry.
- Delete the incomplete draft so resolution falls back to the deployed script (by hash or path).
- Inline the script content into the flow module if it was meant to be a rawscript.
Example fix
// before
writeScript({ path: 'u/user/helper', summary: 'wip' }) // draft without content
// after
writeScript({ path: 'u/user/helper', content: 'export function main(){}', language: 'bun' }) Defensive patterns
Strategy: type-guard
Validate before calling
const draft = await getGlobalDraft(workspace, 'script', moduleValue.path)
if (draft && (typeof draft.value !== 'string' || !draft.language)) {
await deleteGlobalDraft(workspace, 'script', moduleValue.path)
} Type guard
function hasContentAndLang(d: unknown): d is { value: string; language: ScriptLang } {
const x = d as any
return !!x && typeof x.value === 'string' && typeof x.language === 'string'
} Try / catch
try {
return await loadModuleScript(moduleValue)
} catch (e) {
if (String(e.message).includes('missing content or language')) {
return ScriptService.getScriptByHash({ workspace, hash: moduleValue.hash! })
}
throw e
} Prevention
- Complete script drafts (content + language) before running flow edit sessions.
- Delete abandoned partial drafts for module script paths.
- Prefer inlining module code so resolution does not depend on separate script drafts.
When it happens
Trigger: getGlobalDraft(workspace, 'script', moduleValue.path) returns a draft with non-string value or missing language while loading a module's script for a flow inline-script operation.
Common situations: A partial write_script draft for the module's script path was left by an interrupted earlier call; the draft holds only a summary; the module points at a script path whose draft was created but never filled.
Related errors
- Draft script "${path}" is missing content or language.
- Draft flow "${path}" has no value.
- path and hash_ are mutually exclusive
- path or hash_ must be provided
- preprocessor function is missing
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/a36be0d0c06b538e.
Report an issue: GitHub.