windmill-labs/windmill · warning
No draft found for " ".
Error message
No draft found for ${type} "${path}". What it means
Thrown by discard_draft when getGlobalDraft returns no draft for the given type/path (and trigger_kind): there is nothing to discard. The tool refuses so the model knows its assumption of a pending draft is wrong.
Solutions
- Verify a draft exists first (read the item's draft status) before discarding
- If the goal was to undo changes, deploy or rebase instead if a draft is actually present with different args
- Check type, path, and trigger_kind spelling against the item that was edited
Example fix
// before
discard_draft({ type: 'script', path: 'u/admin/cleanup' }) // no draft exists
// after
// rebase_draft can recover changes only if a draft exists; if none:
// proceed without action — the item has no pending chat edits Defensive patterns
Strategy: validation
Validate before calling
const draft = await getGlobalDraft(workspace, args.type, args.path, args.trigger_kind)
if (!draft) {
return // nothing to discard
} Type guard
function draftExists(d: unknown): boolean {
return d !== null && d !== undefined
} Try / catch
try {
await discardDraft(args)
} catch (e) {
if (e instanceof Error && e.message.startsWith('No draft found')) {
// no pending chat edits — proceed without action
}
} Prevention
- Check draft existence before discard; make discards idempotent
- Don't discard after a successful deploy — deploying clears the draft
- Verify exact type/path/trigger_kind match what was edited
When it happens
Trigger: discard_draft is called when no draft exists — the item was never edited in this session, the draft was already discarded/deployed, or type/path/trigger_kind don't match the stored draft key.
Common situations: Double-discard after an earlier successful discard; deploying erased the draft so discard is unnecessary; wrong path casing or wrong trigger_kind so the lookup misses.
Related errors
- App " " has no backend runnable " ". Available runnables: .
- Backend runnable " " not found in app " ".
- This draft " " was started from an older deployed version…
- trigger_kind is required when discarding a trigger draft.
- AI agent modules "`).join(', ')} need a provider input…
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/e90ec53c982a2b4c.
Report an issue: GitHub.
Appendix: source
Thrown at frontend/src/lib/components/copilot/chat/global/core.ts:6151
resource: 'variable',
path
}
}
async function discardLocalDraft(
args: { type: WorkspaceItemType; path: string; trigger_kind?: TriggerKind },
ctx: WriteDraftCtx
): Promise<string> {
const { workspace, toolId, toolCallbacks } = ctx
const { type, path, trigger_kind: triggerKind } = args
if (type === 'trigger' && !triggerKind) {
throw new Error('trigger_kind is required when discarding a trigger draft.')
}
const draft = await getGlobalDraft(workspace, type, path, triggerKind)
if (!draft) {
throw new Error(`No draft found for ${type} "${path}".`)
}
await deleteGlobalDraft(workspace, type, path, triggerKind)
// The chat's touch on the item is undone — drop it from the mask so a
// pre-existing deployed item doesn't keep reading as this chat's edit.
const discardedKind = itemKindFor(type, triggerKind)
if (discardedKind) {
toolCallbacks.onItemDiscarded?.(
discardedKind,
getGlobalDraftStoragePath(workspace, type, path, triggerKind)
)
}
toolCallbacks.setToolStatus(toolId, {
content: `Discarded ${type} "${path}" draft`,
result: 'Draft discarded'
})View on GitHub (pinned to e474e8803c)