windmill-labs/windmill · error
This ${type} draft "${path}" was started from an older deplo
Error message
This ${type} draft "${path}" was started from an older deployed version (forked from ${base}, latest is ${head}). Deploying now would overwrite the version deployed since. Call rebase_draft to discard the stale draft and get your changes back as a diff, then re-apply them (the new draft re-bases onto the latest version) and deploy. To deploy as-is and replace the newer version, call deploy_workspace_item again with force: true. What it means
The deploy_workspace_item tool detects that the chat's draft was forked from deployed version `base` while the item's latest deployed version is now `head` (base !== head). Deploying would silently clobber the newer deployment, so it throws with recovery guidance: rebase the draft, or pass force: true to overwrite deliberately.
Source
Thrown at frontend/src/lib/components/copilot/chat/global/core.ts:6194
triggerKind
},
null,
2
)
}
// A draft started from an older deploy would silently overwrite whatever was
// deployed since. Block the deploy and point the model at rebase_draft, unless it
// explicitly forces the overwrite. `base`/`head` undefined ⇒ can't tell ⇒ allow.
function assertDraftBasedOnLatest(
type: WorkspaceItemType,
path: string,
base: string | number | undefined,
head: string | number | undefined,
force: boolean | undefined
): void {
if (force || base == null || head == null || base === head) return
throw new Error(
`This ${type} draft "${path}" was started from an older deployed version (forked from ${base}, ` +
`latest is ${head}). Deploying now would overwrite the version deployed since. Call rebase_draft to ` +
`discard the stale draft and get your changes back as a diff, then re-apply them (the new draft ` +
`re-bases onto the latest version) and deploy. To deploy as-is and replace the newer version, call ` +
`deploy_workspace_item again with force: true.`
)
}
// Discard a stale draft and return its own changes (vs the fork base) as a diff so
// the model can re-apply them on the latest deploy. Discarding rather than resetting
// keeps the base pointer honest (the next write re-bases on the current head) and
// fails safe: a premature deploy hits "no draft" instead of silently shipping the
// latest unchanged.
async function rebaseDraft(
args: { type: WorkspaceItemType; path: string },
ctx: WriteDraftCtx
): Promise<string> {
switch (args.type) {View on GitHub (pinned to e474e8803c)
Solutions
- Call rebase_draft to discard the stale draft and receive the changes as a diff, re-apply them onto the latest version, then deploy
- If overwriting the newer deployment is intentional, re-call deploy_workspace_item with force: true
- Coordinate with whoever deployed the newer version before choosing force
Example fix
// before
deploy_workspace_item({ type: 'script', path: 'u/admin/cleanup' })
// after — option 1 (safe)
rebase_draft({ type: 'script', path: 'u/admin/cleanup' }) // then re-apply changes and deploy
// after — option 2 (overwrite intentionally)
deploy_workspace_item({ type: 'script', path: 'u/admin/cleanup', force: true }) Defensive patterns
Strategy: validation
Validate before calling
const deployed = await getDeployedVersion(type, path)
if (draft.baseVersion !== deployed.version) {
// draft is stale: prefer rebase_draft over deploying
} Try / catch
try {
await deployWorkspaceItem(args)
} catch (e) {
if (e instanceof Error && e.message.includes('older deployed version')) {
await rebaseDraft(args) // then re-apply changes and deploy
// or intentionally: await deployWorkspaceItem({ ...args, force: true })
}
} Prevention
- Check the deployed version against the draft's base before every deploy in shared environments
- Prefer rebase_draft when unsure — force overwrites teammates' work silently
- Re-run deployments promptly after edits to shrink the stale-draft window
When it happens
Trigger: Someone (or another chat/CLI deploy) deployed a newer version of the same script/flow/app/trigger after this chat's draft was created, and the chat then calls deploy_workspace_item without force.
Common situations: Parallel editing via UI and AI chat; a teammate deployed while the agent worked; re-running an old chat session whose draft predates recent deployments.
Related errors
- trigger_kind is required when discarding a trigger draft.
- No draft found for ${type} "${path}".
- This forked workspace '${workspaceId}' (${workspaceName}) al
- Invalid AI agent provider configuration: ${errors.join('\n')
- AI agent modules ${providerless.map((id) => `"${id}"`).join(
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/d17f176d1820ad26.
Report an issue: GitHub.