Skip to content

<svg><template> crashes: Cannot read properties of undefined (reading 'nodeName') #17

Closed as not planned

Description

@AIEPhoenix

Initial checklist

  • I read the support docs
  • I read the contributing guide
  • I agree to follow the code of conduct
  • I searched issues and couldn’t find anything (or linked relevant results below)

Affected package and version

hast-util-from-parse5@8.0.3

Steps to reproduce

import {fromParse5} from 'hast-util-from-parse5'
import {parseFragment} from 'parse5'

fromParse5(parseFragment('<svg><template>x</template></svg>'))

An unclosed <svg><template> is enough, and <math><template> behaves the same:

fromParse5(parseFragment('<svg><template>'))
fromParse5(parseFragment('<math><template>x</template></math>'))

Actual behavior

TypeError: Cannot read properties of undefined (reading 'nodeName')
    at one (lib/index.js:72)
    at element (lib/index.js:204)

Reachable through every HTML→hast path that uses this utility: hast-util-raw (so rehype-raw on markdown containing that raw HTML), hast-util-from-html, and rehype-parse — whole-document mode included.

Expected behavior

No crash; the foreign template converts like any other foreign element.

Cause

element() switches to the template-contents branch on the tag name alone:

if (result.tagName === 'template') {
  const reference = /** @type {DefaultTreeAdapterMap['template']} */ (node)
  // …
  const content = /** @type {Root} */ (one(state, reference.content))

parse5 — per the HTML spec — attaches template contents only to an HTML-namespace template. Inside foreign content a <template> is an ordinary foreign element: its children live in childNodes, and its content is undefined, so one(state, undefined) throws.

Fix

Guard the branch on the field actually being present:

if (result.tagName === 'template' && 'content' in node && node.content !== undefined) {

The foreign template then takes the ordinary element path, and hastscript normalizes its children onto content anyway, so the converted shape matches the HTML form. PR with tests incoming.

Runtime / package manager

Node 22 / npm — but the crash is environment-independent.

Activity

  1. added
    👋 phase/newPost is being triaged automatically
    🤞 phase/openPost is being triaged manually
    and removed
    👋 phase/newPost is being triaged automatically
    on Aug 24, 2026
  2. AIEPhoenix commented on Aug 24, 2026

    @AIEPhoenix
    Author

    Closing as a duplicate of #15, which reported the same crash three weeks earlier (I only found it after filing). #16 has a fix ready.

  3. github-actions commented on Aug 24, 2026

    @github-actions

    Hi! This was closed. Team: If this was fixed, please add phase/solved. Otherwise, please add one of the no/* labels.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    🤞 phase/openPost is being triaged manually

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions