can1357/oh-my-pi · error
Widget content missing
Error message
Widget content missing
What it means
The extension UI widget hook registered with setHookWidget provided neither static content nor a render function. #createHookWidget expects the widget's `content` to be either an array of renderables or a function (content(this.ctx.ui, theme)); when it is undefined the widget cannot be rendered and this error is thrown. It indicates a malformed extension widget registration rather than a rendering problem.
Source
Thrown at packages/coding-agent/src/modes/controllers/extension-ui-controller.ts:360
#removeHookWidget(widgets: Map<string, ExtensionUiComponent>, key: string): void {
const existing = widgets.get(key);
existing?.dispose?.();
widgets.delete(key);
}
#createHookWidget(content: ExtensionWidgetContent): ExtensionUiComponent {
if (Array.isArray(content)) {
const container = new Container();
for (const line of content.slice(0, MAX_WIDGET_LINES)) {
container.addChild(new Text(line, 1, 0));
}
if (content.length > MAX_WIDGET_LINES) {
container.addChild(new Text(theme.fg("muted", "... (widget truncated)"), 1, 0));
}
return container;
}
if (content === undefined) {
throw new Error("Widget content missing");
}
return content(this.ctx.ui, theme);
}
#rebuildHookWidgets(): void {
this.#renderHookWidgetContainer(this.ctx.hookWidgetContainerAbove, this.#hookWidgetsAbove, true, true);
this.#renderHookWidgetContainer(this.ctx.hookWidgetContainerBelow, this.#hookWidgetsBelow, false, false);
this.ctx.ui.requestRender();
}
#renderHookWidgetContainer(
container: Container,
widgets: Map<string, ExtensionUiComponent>,
spacerWhenEmpty: boolean,
leadingSpacer: boolean,
): void {
container.clear();
View on GitHub (pinned to 9690622007)
Solutions
- Fix the extension to always supply `content` — either a renderable array or a `(ui, theme) => ...` function
- In the extension, fall back to placeholder content (e.g. an empty container) when data is unavailable instead of undefined
- Disable or update the offending extension to a version compatible with the current widget API
- Guard the extension's widget registration with a check that content is defined before calling setHookWidget
Example fix
// before
widget.setContent(data?.renderable); // may be undefined
// after
widget.setContent(data?.renderable ?? [new Text(theme.fg('muted', 'no data'), 1, 0)]); Defensive patterns
Strategy: validation
Validate before calling
// Before registering an extension widget
if (widget.content === undefined) {
throw new Error('Extension widget must define content (renderables or render function)');
}
extensionUi.setHookWidget(widget); Type guard
function hasWidgetContent(w: { content?: unknown }): w is { content: NonNullable<unknown> } {
return w.content !== undefined;
} Try / catch
try {
extensionUi.setHookWidget(widget);
} catch (err) {
if (err instanceof Error && err.message === 'Widget content missing') {
logger.warn('Extension widget rejected: no content', { id: widget.id });
}
} Prevention
- Always initialize widget.content with a fallback renderable
- Version-check extension APIs before registering widgets
- Never pass through possibly-undefined values from async data fetches into content
When it happens
Trigger: An extension/hook calls setHookWidget with a widget object whose `content` field is undefined — e.g. the hook computed content conditionally and returned undefined, or passed an object with a misspelled/missing content key.
Common situations: A third-party extension built against an older widget API where content was optional; an extension that returns undefined from an async lookup (e.g. failed fetch for widget data) and passes it straight through; a typo like `{ ctx }` instead of `{ content }`.
Related errors
- No messages to continue from
- Cannot continue from message role: assistant
- Gemini Files API cannot delete a handle from another provide
- Gemini Files API delete requires a valid file name
- maxAgents must be a positive integer
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/ac75f5768157aa64.
Report an issue: GitHub.