{"record":{"id":"385b8604164df880","repo":"windmill-labs/windmill","slug":"unsupported-draft-type-type","errorCode":null,"errorMessage":"Unsupported draft type \"${type}\".","messagePattern":"Unsupported draft type \"(.+?)\"\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/copilot/chat/global/userDraftAdapter.ts","lineNumber":422,"sourceCode":"\t\t\titem: WorkspaceItem\n\t\t\titemKind: UserDraftItemKind\n\t\t\tstoragePath: string\n\t\t\tmessage: string\n\t  }\n\n// Persist a built draft value. `UserDraft.seed` reflects it into an open editor's\n// cell WITHOUT a double-POST (no-ops if no cell; its seedNextWrite suppresses the\n// cell's autosave mirror), then the awaited immediate save is the single source of\n// persistence + conflict detection against the shared baseline. force overwrites.\nexport async function persistGlobalDraft(\n\tworkspace: string,\n\ttype: WorkspaceItemType,\n\tpath: string,\n\tvalue: unknown,\n\topts: { triggerKind?: TriggerKind; force?: boolean } = {}\n): Promise<DraftPersistResult> {\n\tconst itemKind = itemKindFor(type, opts.triggerKind)\n\tif (!itemKind) throw new Error(`Unsupported draft type \"${type}\".`)\n\tconst storagePath = resolveDraftStoragePath(workspace, itemKind, path)\n\tUserDraft.seed(itemKind, storagePath, value, { workspace })\n\tawait UserDraftDbSyncer.save({\n\t\tworkspace,\n\t\titemKind,\n\t\tpath: storagePath,\n\t\tvalue,\n\t\timmediate: true,\n\t\tforce: opts.force\n\t})\n\tconst { displayPath, isLiveDraft } = liveDisplayPath(workspace, itemKind, storagePath)\n\tconst item = userDraftEntryToWorkspaceItem(\n\t\t{ workspace, itemKind, path: storagePath, value },\n\t\tdisplayPath,\n\t\tisLiveDraft\n\t)\n\tif (!item) throw new Error(`Could not synthesize ${type} draft \"${path}\".`)\n\t// A failed save (network/5xx) is recorded in the syncer's failure map, not","sourceCodeStart":404,"sourceCodeEnd":440,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/copilot/chat/global/userDraftAdapter.ts#L404-L440","documentation":"persistGlobalDraft() is the chat's write path for user drafts (scripts, flows, apps, resources, variables, schedules, triggers). Before persisting it maps the chat-facing WorkspaceItemType (plus optional triggerKind) to an internal UserDraftItemKind via itemKindFor(); types that have no draft representation — or 'trigger' without a triggerKind — return undefined and this error is thrown. It is a fail-fast guard so an unmappable type never lands in the draft store.","triggerScenarios":"Calling persistGlobalDraft/saveGlobalAppDraft with a WorkspaceItemType outside {'script','flow','resource','variable','app','schedule','trigger'}; or type==='trigger' without opts.triggerKind set (itemKindFor returns undefined for kindless triggers).","commonSituations":"A chat tool passes a new workspace item type added to the app but not yet mapped in itemKindFor; a tool builds the call dynamically and drops the triggerKind; typos like 'raw_app' passed directly (chat type is 'app').","solutions":["Set opts.triggerKind when type is 'trigger' (e.g. { triggerKind: 'websocket' }).","Use only supported WorkspaceItemType values: script, flow, resource, variable, app, schedule, trigger.","If you added a new item type, extend the switch in itemKindFor (userDraftAdapter.ts:84) to map it to a UserDraftItemKind.","Check the value at runtime: if itemKindFor(type, triggerKind) is undefined, surface a friendly message instead of calling persistGlobalDraft."],"exampleFix":"// before\nawait persistGlobalDraft(workspace, 'trigger', path, value)\n// after\nawait persistGlobalDraft(workspace, 'trigger', path, value, { triggerKind: 'websocket' })","handlingStrategy":"validation","validationCode":"import { itemKindFor } from '$lib/components/copilot/chat/global/userDraftAdapter'\nif (!itemKindFor(type, opts?.triggerKind)) {\n  throw new Error(`Cannot draft item of type \"${type}\"` + (type === 'trigger' && !opts?.triggerKind ? ' without a triggerKind' : ''))\n}","typeGuard":"function isDraftableType(type: WorkspaceItemType, triggerKind?: TriggerKind): boolean {\n  return itemKindFor(type, triggerKind) !== undefined\n}","tryCatchPattern":"try {\n  await persistGlobalDraft(workspace, type, path, value, opts)\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Unsupported draft type')) {\n    notify(`\"${type}\" drafts are not supported`)\n  } else throw e\n}","preventionTips":["Always pass triggerKind when drafting triggers","Keep itemKindFor's switch in sync whenever WorkspaceItemType gains a member (it is exhaustive — rely on TS)","Validate tool arguments against the supported type union before invoking draft APIs"],"tags":["typescript","validation","unsupported-type"],"backgroundTag":"unsupported-draft-type","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"}