pixijs/pixijs · error · Error
[HTMLSource] resource must be a direct child of the owning c
Error message
[HTMLSource] resource must be a direct child of the owning canvas. Append the element to the canvas before constructing this source.
What it means
The third HTMLSource gate: even after a canvas is found, the resource must be a DIRECT child of that canvas (resource.parentElement === canvas). HTML-in-Canvas integration requires this parent-child relationship so the browser associates the element with the correct canvas surface. An element nested deeper, or attached to a different parent, fails this check.
Source
Thrown at src/html-source/HTMLSource.ts:269
{
throw new Error('[HTMLSource] resource is required.');
}
super(options);
const canvas = options.canvas ?? this._inferCanvas(options.resource);
if (!canvas)
{
throw new Error(
// eslint-disable-next-line max-len
'[HTMLSource] Could not determine the owning canvas. Append the element to the canvas before constructing this source, or pass the `canvas` option.',
);
}
if (options.resource.parentElement !== canvas)
{
throw new Error(
// eslint-disable-next-line max-len
'[HTMLSource] resource must be a direct child of the owning canvas. Append the element to the canvas before constructing this source.',
);
}
this.canvas = canvas;
this._autoUpdate = options.autoUpdate !== false;
this._onPaintBound = this._onPaint.bind(this);
// Without requestPaint (or with auto-update off) there is no first paint to wait for.
this._isReady = !this._autoUpdate || !canvas.requestPaint;
if (options.autoLayout !== false)
{
canvas.setAttribute('layoutsubtree', '');
}
if (this._autoUpdate)View on GitHub (pinned to 4b141e3ced)
Solutions
- Append the resource directly to the canvas element, not to an intermediate wrapper.
- Remove intermediate containers or flatten the DOM structure under the canvas.
- If a wrapper is required for layout, make the wrapper itself the HTMLSource resource and parent it to the canvas.
- After any DOM move, re-verify resource.parentElement === canvas.
Example fix
// before
canvas.appendChild(wrapper);
wrapper.appendChild(el);
const source = new HTMLSource({ resource: el, canvas });
// after
canvas.appendChild(el);
const source = new HTMLSource({ resource: el, canvas }); Defensive patterns
Strategy: validation
Validate before calling
if (resource.parentElement !== canvas) {
canvas.appendChild(resource);
}
const source = new HTMLSource({ resource, canvas }); Type guard
function isDirectChildOf(el: HTMLElement, canvas: HTMLCanvasElement): boolean {
return el.parentElement === canvas;
} Prevention
- Append the resource directly to the canvas, not a wrapper.
- Re-verify parentage after any DOM move.
- Avoid intermediate positioning containers under the canvas.
When it happens
Trigger: Appending the resource to a wrapper div that is itself a child of the canvas (element is a grandchild); moving the element to another container after construction; passing a canvas via options.canvas that is not the element's actual parent.
Common situations: Wrapping overlays in a positioning container for layout; framework that inserts intermediate wrapper nodes; re-parenting during animations.
Related errors
- [HTMLSource] Could not determine the owning canvas. Append t
- [HTMLSource] resource is required.
- [ElementImageSource] resource is required.
- [HTMLSource] WebGLRenderingContext.texElementImage2D is not
- [HTMLSource] GPUQueue.copyElementImageToTexture is not avail
AI-assisted analysis of pixijs/pixijs@4b141e3ced (2026-08-12).
Data as JSON: /api/errors/2c94f9d5e9daee4a.
Report an issue: GitHub.