windmill-labs/windmill · warning

trigger_kind is required when discarding a trigger draft.

Error message

trigger_kind is required when discarding a trigger draft.

What it means

The discard_draft tool requires a `trigger_kind` argument when discarding a draft of type 'trigger', because draft storage for triggers is keyed by trigger kind in addition to path. The tool throws before touching any draft when the kind is missing.

Source

Thrown at frontend/src/lib/components/copilot/chat/global/core.ts:6146

function createOpenVariableAction(path: string): ToolDisplayAction {
	return {
		id: `open-deployed-variable:${path}`,
		type: 'open_created_resource',
		label: 'Open variable',
		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)
		)
	}

View on GitHub (pinned to e474e8803c)

Solutions

  1. Re-call discard_draft including trigger_kind (e.g. 'websocket', 'schedule', 'http')
  2. List the item's triggers to determine which trigger_kind applies
  3. For non-trigger types, ensure type is not 'trigger' if no kind is known

Example fix

// before
discard_draft({ type: 'trigger', path: 'u/admin/ingest' })
// after
discard_draft({ type: 'trigger', path: 'u/admin/ingest', trigger_kind: 'websocket' })
Defensive patterns

Strategy: validation

Validate before calling

if (args.type === 'trigger' && !args.trigger_kind) {
  throw new Error('trigger_kind is required when discarding a trigger draft.')
}

Type guard

function canDiscard(args: { type: string; trigger_kind?: string }):
  args is { type: 'trigger'; trigger_kind: string } | { type: string; trigger_kind?: string } {
  return args.type !== 'trigger' || !!args.trigger_kind
}

Try / catch

try {
  await discardDraft(args)
} catch (e) {
  if (e instanceof Error && e.message.includes('trigger_kind is required')) {
    // look up the item's trigger kind and retry with it
  }
}

Prevention

When it happens

Trigger: discard_draft is called with `type: 'trigger'` but `trigger_kind` is undefined/empty — the model omitted the argument or called with only path.

Common situations: Model generalizing from script/flow discards (which need no kind) to triggers; schema for the tool not fully respected by the model; args constructed programmatically without the optional field.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/6a5c527231905c72. Report an issue: GitHub.