windmill-labs/windmill · error · Error
${drawerConfigs[request.key].label} drawer is not ready
Error message
${drawerConfigs[request.key].label} drawer is not ready What it means
getEditor in CreatedResourceActionDrawers.svelte waits one tick plus one animation frame for the drawer's editor component to mount, then throws if it is still undefined. The thrown message names the drawer label from drawerConfigs, indicating the drawer UI was asked to open but its editor instance never became available.
Source
Thrown at frontend/src/lib/components/copilot/chat/CreatedResourceActionDrawers.svelte:116
return current ? `Edit ${drawerConfigs[current.key].label} ${current.path}` : 'Edit trigger'
})
async function getEditor(request: ActiveDrawerState): Promise<EditorHandle | undefined> {
await request.promise
await tick()
await nextAnimationFrame()
if (activeDrawer?.id !== request.id) {
return undefined
}
if (!editor) {
await tick()
await nextAnimationFrame()
}
if (!editor) {
throw new Error(`${drawerConfigs[request.key].label} drawer is not ready`)
}
return editor
}
async function openCreatedResource(action: ToolDisplayAction) {
if (action.type !== 'open_created_resource') {
return
}
if (action.resource === 'resource') {
await resourceEditorDrawer?.initEdit(action.path)
return
}
if (action.resource === 'variable') {
await variableEditor?.editVariable(action.path)
return
}View on GitHub (pinned to e474e8803c)
Solutions
- Verify request.key exists in drawerConfigs and maps to a drawer that renders an editor
- Increase/verify the wait: ensure the drawer markup is actually rendered (not behind an {#if} that is still false) before calling getEditor
- Wrap the getEditor call in try/catch and surface a retry or close the drawer instead of an unhandled rejection
Example fix
// before
const editor = await getEditor(request)
// after
let editor
try {
editor = await getEditor(request)
} catch {
sendUserToast('Could not open the editor drawer, please retry', true)
return
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!drawerConfigs[request.key]) { sendUserToast('Unknown drawer', true); return } Type guard
function hasDrawer(key: string): key is keyof typeof drawerConfigs { return key in drawerConfigs } Try / catch
try { const editor = await getEditor(request) } catch { sendUserToast('Editor failed to open, please retry', true); activeDrawer = undefined } Prevention
- Confirm every emitted request.key exists in drawerConfigs
- Don't close the drawer synchronously after requesting it
- Render the drawer markup unconditionally while a request is pending
When it happens
Trigger: openCreatedResource / openDrawer sets a request; getEditor is called and after `await tick()` + `await nextAnimationFrame()` the `editor` variable is still falsy — e.g. the drawer component failed to mount, the request.key has no matching drawerConfig entry rendering an editor, or the drawer was closed synchronously before mounting.
Common situations: Race between the AI chat applying a tool action and the drawer's conditional rendering; a key not present in drawerConfigs so no editor is ever created; component torn down mid-await so the editor binding never populates.
Related errors
- PlanWriteRefusedError
- The tool list for ${path} changed while it was loading. Try
- Can't create script from non-inline script
- no first step found
- only scripts can be used as a input schema
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/1bc391ea14cca434.
Report an issue: GitHub.