windmill-labs/windmill · error

Failed to create ${triggerConfig.label} "${requestBody.path}

Error message

Failed to create ${triggerConfig.label} "${requestBody.path}": ${formatToolError(error)}

What it means

create_trigger wraps its backend create call (per-kind Service, e.g. HttpTriggerService.createHttpTrigger) so any failure is rethrown as `Failed to create <label> "<path>": <detail>`. Args already passed zod validation, so this reflects server-side rejection of the trigger creation itself.

Source

Thrown at frontend/src/lib/components/copilot/chat/workspaceTools.ts:497

					...(emailAddress ? { email_address: emailAddress } : {})
				}
				toolCallbacks.setToolStatus(toolId, {
					content: emailAddress
						? `Created ${triggerConfig.label} "${requestBody.path}" (send email to ${emailAddress})`
						: `Created ${triggerConfig.label} "${requestBody.path}"`,
					result: toolResult,
					actions: [
						createOpenTriggerAction(
							parsedArgs.kind,
							requestBody.path,
							targetKind,
							triggerConfig.label
						)
					]
				})
				return JSON.stringify(toolResult)
			} catch (error) {
				throw new Error(
					`Failed to create ${triggerConfig.label} "${requestBody.path}": ${formatToolError(error)}`
				)
			}
		} catch (error) {
			return setToolError(toolCallbacks, toolId, error)
		}
	}
}

const workspaceMutationTools = [
	createScheduleTool,
	createTriggerTool,
	getTriggerSchemaTool,
	getScheduleSchemaTool
]

export function createWorkspaceMutationTools<T>(): Tool<T>[] {
	return workspaceMutationTools as Tool<T>[]

View on GitHub (pinned to e474e8803c)

Solutions

  1. Read the wrapped backend detail and fix the offending config field
  2. Verify external resources (broker URLs, DB connections, HTTP routes) are reachable and correct for the trigger kind
  3. Use a unique trigger path, or delete the existing trigger at that path
  4. Check workspace permissions for creating triggers of that kind

Example fix

// before
create_trigger({ kind: 'kafka', path: 'u/u/kafka_t', config: { kafka_resource_path: 'u/u/k', topics: 'orders' } })
// after (topics must be an array per schema)
create_trigger({ kind: 'kafka', path: 'u/u/kafka_t', config: { kafka_resource_path: 'u/u/k', topics: ['orders'] } })
Defensive patterns

Strategy: try-catch

Validate before calling

const existing = await listTriggers(workspace)
if (existing.some((t) => t.path === path)) throw new Error(`Trigger ${path} already exists`)

Try / catch

try {
  await triggerConfig.create({ workspace, requestBody })
} catch (e) {
  const msg = (e as Error).message
  if (/already exists/i.test(msg)) return createTrigger({ ...args, path: uniquePath() })
  if (/config/i.test(msg)) return fixConfigPerKind(args) // per backend detail
  throw e
}

Prevention

When it happens

Trigger: The per-kind trigger Service returns an error: duplicate trigger path, invalid config for the kind (bad Kafka topic, missing Postgres column, unreachable AMQP/HTTP config), email trigger misconfiguration, or missing permissions.

Common situations: Config pointing at resources that don't exist or aren't reachable from the instance (Kafka brokers, Postgres connection); email trigger with a local_part colliding with an existing address; path already taken; workspace permissions too low.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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