moeru-ai/airi · error · Error
id is required to update a widget.
Error message
id is required to update a widget.
What it means
Thrown by executeWidgetAction when action='update' but no widget id can be resolved. normalizedId is computed as input.id?.trim() || undefined, so an empty or whitespace id becomes undefined and fails the guard at widgets.ts:275. The update action must target an existing widget by id, since updateWidget IPC requires the id to locate the live widget.
Source
Thrown at apps/stage-tamagotchi/src/renderer/stores/tools/builtin/widgets.ts:275
const componentProps = normalizeComponentProps(input.componentProps)
const sanitizedComponentProps = sanitizeComponentPropsForDispatch(input.componentName, componentProps)
const windowSize = resolveWindowSize(input.componentName, sanitizedComponentProps, input.windowSize)
const ttlMs = input.ttlSeconds ? Math.floor(input.ttlSeconds * 1000) : 0
const id = await invokers.addWidget({
id: normalizedId,
componentName: input.componentName,
componentProps: sanitizedComponentProps,
size: input.size ?? 'm',
...(input.alwaysOnTop === undefined ? {} : { alwaysOnTop: input.alwaysOnTop }),
...(windowSize === undefined ? {} : { windowSize }),
ttlMs,
})
return `Spawned widget${id ? ` (${id})` : ''}.`
}
case 'update': {
if (!normalizedId)
throw new Error('id is required to update a widget.')
const componentProps = normalizeComponentProps(input.componentProps)
const sanitizedComponentProps = sanitizeComponentPropsForDispatch(input.componentName, componentProps)
const windowSize = resolveWindowSize(input.componentName, sanitizedComponentProps, input.windowSize)
await invokers.updateWidget({
id: normalizedId,
componentProps: sanitizedComponentProps,
...(input.alwaysOnTop === undefined ? {} : { alwaysOnTop: input.alwaysOnTop }),
...(windowSize === undefined ? {} : { windowSize }),
})
return `Updated widget (${normalizedId}).`
}
case 'remove': {
if (!normalizedId)
throw new Error('id is required to remove a widget.')
await invokers.removeWidget({ id: normalizedId })View on GitHub (pinned to 27111382b4)
Solutions
- Pass the id returned by the prior spawn call when issuing an update.
- If you only know componentName, spawn a new widget instead, or track the id from the spawn result string 'Spawned widget (ID).'
- For LLM-driven flows, include the spawned widget id in the conversation context so the model can echo it on update.
Example fix
// before
await executeWidgetAction({ action: 'update', id: ' ', componentProps: { city: 'Osaka' } })
// after
await executeWidgetAction({ action: 'update', id: 'w1', componentProps: { city: 'Osaka' } }) Defensive patterns
Strategy: validation
Validate before calling
const normalizedId = input.id?.trim()
if (input.action === 'update' && !normalizedId)
throw new Error('id is required to update a widget.') Type guard
function hasUpdateId(input) {
return input.action !== 'update' || Boolean(input.id?.trim())
} Try / catch
try {
await executeWidgetAction(input)
} catch (e) {
if (e.message.includes('id is required to update'))
// re-fetch widget id from prior spawn result
throw e
} Prevention
- Persist the id returned by spawn ('Spawned widget (ID).') in caller state.
- In LLM flows, include spawned widget ids in the conversation context for later updates.
When it happens
Trigger: Calling executeWidgetAction({ action: 'update' }) with id omitted, empty, or whitespace. Passing the stage_widgets tool an update turn where the model left id blank because it assumed update-by-componentName.
Common situations: An LLM confuses update (needs id) with spawn (id optional) and sends update without the widget id returned from the prior spawn; a caller reuses a spawn payload object for an update but drops the id field.
Related errors
- componentName is required to spawn a widget.
- id is required to remove a widget.
- Invalid Godot stage scene input payload.
- timeout must be a positive finite number
- Failed to apply server channel configuration
AI-assisted analysis of moeru-ai/airi@27111382b4 (2026-08-12).
Data as JSON: /api/errors/fe2d848c31069629.
Report an issue: GitHub.