windmill-labs/windmill · error
Draft ${type} "${path}" has no value to deploy.
Error message
Draft ${type} "${path}" has no value to deploy. What it means
Thrown by the chat's deployDraft tool when a draft exists for the item (getGlobalDraft returned a record) but its value field is undefined — the draft shell exists without any content to publish. Deploying an undefined value would create or overwrite a workspace item with nothing, so the tool refuses. This is distinct from 'No draft found': the draft slot exists but was never filled (or was cleared).
Source
Thrown at frontend/src/lib/components/copilot/chat/global/core.ts:7267
const { workspace, toolId, toolCallbacks, sessionId } = ctx
const {
type,
path,
trigger_kind: triggerKind,
deployment_message: deploymentMessage,
force
} = args
if (type === 'trigger' && !triggerKind) {
throw new Error('trigger_kind is required when deploying a trigger.')
}
const draft = await getGlobalDraft(workspace, type, path, triggerKind)
if (!draft) {
throw new Error(`No draft found for ${type} "${path}".`)
}
if (draft.value === undefined) {
throw new Error(`Draft ${type} "${path}" has no value to deploy.`)
}
toolCallbacks.setToolStatus(toolId, {
content: `Deploying ${type} "${path}"...`
})
let actions: ToolDisplayAction[] | undefined
// Where the deploy actually lands — the app branch can resolve a different
// target from the draft's own path fields; the mask rename below must track it.
let deployedPath = path
// Appended to the success message when the deploy deliberately left something alone,
// so "deployed" is never read as "everything in the draft was applied".
let deployNote: string | undefined
if (type === 'script' || type === 'flow') {
// Promote the full persisted draft via the shared deploy module — the same
// "promote a draft to deployed" code the compare page's Review & Deploy uses.
// It deploys every field of the draft; the previous local builders droppedView on GitHub (pinned to e474e8803c)
Solutions
- Reload the item's draft in the editor/chat so the value is populated, then deploy again.
- If the draft is genuinely empty, edit the content before deploying.
- Clear the local draft and recreate it if the state appears corrupted.
Example fix
// before
const draft = await getGlobalDraft(ws, 'app', 'a/dashboard') // exists, value undefined
await deployDraft({ type: 'app', path: 'a/dashboard' })
// Error: Draft app "a/dashboard" has no value to deploy.
// after: wait for the draft content to load (or set it) before deploying
await waitForDraftValue('app', 'a/dashboard')
await deployDraft({ type: 'app', path: 'a/dashboard' }) Defensive patterns
Strategy: validation
Validate before calling
const draft = await getGlobalDraft(workspace, type, path, triggerKind)
if (draft && draft.value === undefined) {
throw new Error(`draft ${type} "${path}" has not loaded its content yet`)
}
await deployDraft({ type, path, workspace }) Type guard
function draftHasValue(draft) {
return draft != null && draft.value !== undefined
} Try / catch
try {
await deployDraft(args)
} catch (e) {
if (/has no value to deploy/.test(e.message)) {
// reload the draft content, then retry
} else throw e
} Prevention
- Wait for the draft's content to finish loading before deploying.
- Don't deploy a draft immediately after creating an empty shell record.
- Recreate the draft if local state looks corrupted.
When it happens
Trigger: Calling the deploy tool when draft.value === undefined for the located draft — e.g. a draft record was created by opening the item but its content never loaded/was wiped by a failed sync or a clearing operation.
Common situations: A race where the draft is created before its content fetch resolves and the user (or agent) deploys immediately; a draft reset/cleared by conflict handling; corrupted local IndexedDB draft state after a crashed session.
Related errors
- git ${args.join(" ")} failed (exit ${status}): ${r.stderr ??
- Unknown kind: ${kind}
- Datatable migration ${path} not found in ${workspaceFrom}
- Deletion not supported for kind: ${kind}
- Draft variable "${draftValue.path}" is secret but stages no
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/f849c7f2838a0948.
Report an issue: GitHub.