windmill-labs/windmill · error

Failed to create schedule "${requestBody.path}": ${formatToo

Error message

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

What it means

The final leg of create_schedule — ScheduleService.createSchedule — is wrapped so any backend failure is rethrown as `Failed to create schedule "<path>": <detail>`. By this point the schedule body validated and the cron previewed, so this indicates a server-side rejection: path conflicts, permissions, the target script/flow missing, or transport errors.

Source

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

			})
			try {
				const result = await ScheduleService.createSchedule({ workspace, requestBody })
				const targetKind = getActionTargetKind(requestBody.is_flow)
				const toolResult = {
					success: true,
					path: requestBody.path,
					target_path: requestBody.script_path,
					target_kind: targetKind,
					backend_result: result
				}
				toolCallbacks.setToolStatus(toolId, {
					content: `Created schedule "${requestBody.path}"`,
					result: toolResult,
					actions: [createOpenScheduleAction(requestBody.path, targetKind)]
				})
				return JSON.stringify(toolResult)
			} catch (error) {
				throw new Error(
					`Failed to create schedule "${requestBody.path}": ${formatToolError(error)}`
				)
			}
		} catch (error) {
			return setToolError(toolCallbacks, toolId, error)
		}
	}
}

const EMAIL_TRIGGER_DOCS = 'https://windmill.dev/docs/advanced/email_triggers'

type EmailTriggerAvailability =
	| { available: true; domain: string }
	| { available: false; hint: string }

/**
 * Email triggers only work once an instance superadmin has stood up an SMTP
 * server forwarding to Windmill and set the `email_domain` global setting

View on GitHub (pinned to e474e8803c)

Solutions

  1. Pick a different schedule path or delete the existing schedule with that path first
  2. Check you have permission to create schedules in the workspace
  3. Confirm the target script/flow still exists and is deployed at script_path
  4. Inspect the wrapped backend detail in the message; retry on transient 5xx/network errors

Example fix

// before
create_schedule({ path: 'u/user/nightly', schedule: '0 2 * * *' }) // exists already
// after
create_schedule({ path: 'u/user/nightly_v2', schedule: '0 2 * * *' })
Defensive patterns

Strategy: try-catch

Validate before calling

const existing = await ScheduleService.listSchedules({ workspace })
if (existing.some((s) => s.path === path)) throw new Error(`Schedule ${path} already exists`)

Try / catch

try {
  await createSchedule(body)
} catch (e) {
  const msg = (e as Error).message
  if (/already exists|duplicate/i.test(msg)) {
    await deleteSchedule(path); return createSchedule(body)
  }
  if (/403|permission/i.test(msg)) throw new Error('Missing workspace permissions')
  if (/5\d\d|network/i.test(msg)) return retryWithBackoff(() => createSchedule(body))
  throw e
}

Prevention

When it happens

Trigger: createSchedule returns non-2xx: a schedule with requestBody.path already exists (409/400), user lacks workspace write permission (403), the referenced script_path/is_flow target no longer exists, or a network/5xx error from the backend.

Common situations: Re-running a chat that already created the schedule with the same path; permission-restricted workspaces; the target script was renamed after preview; backend temporarily down.

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/13df4f16052881ab. Report an issue: GitHub.