{"record":{"id":"2c94f9d5e9daee4a","repo":"pixijs/pixijs","slug":"htmlsource-resource-must-be-a-direct-child-of-th","errorCode":null,"errorMessage":"[HTMLSource] resource must be a direct child of the owning canvas. Append the element to the canvas before constructing this source.","messagePattern":"\\[HTMLSource\\] resource must be a direct child of the owning canvas\\. Append the element to the canvas before constructing this source\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/html-source/HTMLSource.ts","lineNumber":269,"sourceCode":"        {\n            throw new Error('[HTMLSource] resource is required.');\n        }\n\n        super(options);\n\n        const canvas = options.canvas ?? this._inferCanvas(options.resource);\n\n        if (!canvas)\n        {\n            throw new Error(\n                // eslint-disable-next-line max-len\n                '[HTMLSource] Could not determine the owning canvas. Append the element to the canvas before constructing this source, or pass the `canvas` option.',\n            );\n        }\n\n        if (options.resource.parentElement !== canvas)\n        {\n            throw new Error(\n                // eslint-disable-next-line max-len\n                '[HTMLSource] resource must be a direct child of the owning canvas. Append the element to the canvas before constructing this source.',\n            );\n        }\n\n        this.canvas = canvas;\n        this._autoUpdate = options.autoUpdate !== false;\n        this._onPaintBound = this._onPaint.bind(this);\n\n        // Without requestPaint (or with auto-update off) there is no first paint to wait for.\n        this._isReady = !this._autoUpdate || !canvas.requestPaint;\n\n        if (options.autoLayout !== false)\n        {\n            canvas.setAttribute('layoutsubtree', '');\n        }\n\n        if (this._autoUpdate)","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/pixijs/pixijs/blob/4b141e3ced7255b39c2114b6bca03421a37b2363/src/html-source/HTMLSource.ts#L251-L287","documentation":"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.","triggerScenarios":"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.","commonSituations":"Wrapping overlays in a positioning container for layout; framework that inserts intermediate wrapper nodes; re-parenting during animations.","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."],"exampleFix":"// before\ncanvas.appendChild(wrapper);\nwrapper.appendChild(el);\nconst source = new HTMLSource({ resource: el, canvas });\n\n// after\ncanvas.appendChild(el);\nconst source = new HTMLSource({ resource: el, canvas });","handlingStrategy":"validation","validationCode":"if (resource.parentElement !== canvas) {\n  canvas.appendChild(resource);\n}\nconst source = new HTMLSource({ resource, canvas });","typeGuard":"function isDirectChildOf(el: HTMLElement, canvas: HTMLCanvasElement): boolean {\n  return el.parentElement === canvas;\n}","tryCatchPattern":null,"preventionTips":["Append the resource directly to the canvas, not a wrapper.","Re-verify parentage after any DOM move.","Avoid intermediate positioning containers under the canvas."],"tags":["html-source","dom","canvas","hierarchy","setup"],"backgroundTag":null,"analyzedSha":"4b141e3ced7255b39c2114b6bca03421a37b2363","analyzedAt":"2026-08-12T17:27:29.507Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}