{"record":{"id":"f849c7f2838a0948","repo":"windmill-labs/windmill","slug":"draft-type-path-has-no-value-to-deploy","errorCode":null,"errorMessage":"Draft ${type} \"${path}\" has no value to deploy.","messagePattern":"Draft (.+?) \"(.+?)\" has no value to deploy\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/copilot/chat/global/core.ts","lineNumber":7267,"sourceCode":"\tconst { workspace, toolId, toolCallbacks, sessionId } = ctx\n\tconst {\n\t\ttype,\n\t\tpath,\n\t\ttrigger_kind: triggerKind,\n\t\tdeployment_message: deploymentMessage,\n\t\tforce\n\t} = args\n\n\tif (type === 'trigger' && !triggerKind) {\n\t\tthrow new Error('trigger_kind is required when deploying a trigger.')\n\t}\n\n\tconst draft = await getGlobalDraft(workspace, type, path, triggerKind)\n\tif (!draft) {\n\t\tthrow new Error(`No draft found for ${type} \"${path}\".`)\n\t}\n\tif (draft.value === undefined) {\n\t\tthrow new Error(`Draft ${type} \"${path}\" has no value to deploy.`)\n\t}\n\n\ttoolCallbacks.setToolStatus(toolId, {\n\t\tcontent: `Deploying ${type} \"${path}\"...`\n\t})\n\n\tlet actions: ToolDisplayAction[] | undefined\n\t// Where the deploy actually lands — the app branch can resolve a different\n\t// target from the draft's own path fields; the mask rename below must track it.\n\tlet deployedPath = path\n\t// Appended to the success message when the deploy deliberately left something alone,\n\t// so \"deployed\" is never read as \"everything in the draft was applied\".\n\tlet deployNote: string | undefined\n\n\tif (type === 'script' || type === 'flow') {\n\t\t// Promote the full persisted draft via the shared deploy module — the same\n\t\t// \"promote a draft to deployed\" code the compare page's Review & Deploy uses.\n\t\t// It deploys every field of the draft; the previous local builders dropped","sourceCodeStart":7249,"sourceCodeEnd":7285,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/copilot/chat/global/core.ts#L7249-L7285","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nconst draft = await getGlobalDraft(ws, 'app', 'a/dashboard') // exists, value undefined\nawait deployDraft({ type: 'app', path: 'a/dashboard' })\n// Error: Draft app \"a/dashboard\" has no value to deploy.\n\n// after: wait for the draft content to load (or set it) before deploying\nawait waitForDraftValue('app', 'a/dashboard')\nawait deployDraft({ type: 'app', path: 'a/dashboard' })","handlingStrategy":"validation","validationCode":"const draft = await getGlobalDraft(workspace, type, path, triggerKind)\nif (draft && draft.value === undefined) {\n  throw new Error(`draft ${type} \"${path}\" has not loaded its content yet`)\n}\nawait deployDraft({ type, path, workspace })","typeGuard":"function draftHasValue(draft) {\n  return draft != null && draft.value !== undefined\n}","tryCatchPattern":"try {\n  await deployDraft(args)\n} catch (e) {\n  if (/has no value to deploy/.test(e.message)) {\n    // reload the draft content, then retry\n  } else throw e\n}","preventionTips":["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."],"tags":["draft","empty-state","deploy","tool-call"],"backgroundTag":"draft-empty-value","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"}