wavetermdev/waveterm · error
doctype not supported
Error message
doctype not supported
What it means
vdom.Bind's HTML tokenizer encountered a <!DOCTYPE ...> declaration, which the minimal bind-HTML grammar does not support. Bind expects a plain fragment of HTML (elements, text, comments, bind tags) — a doctype means a full HTML document was passed where only a fragment is expected, so parsing stops with this error.
Source
Thrown at pkg/vdom/vdom_html.go:385
appendChildToStack(elemStack, &VDomElem{Tag: WaveTextTag, Props: map[string]any{"text": binding}})
continue
}
elem := tokenToElem(token, params)
appendChildToStack(elemStack, elem)
case htmltoken.TextToken:
if token.Data == "" {
continue
}
textStr := processTextStr(token.Data)
if textStr == "" {
continue
}
elem := TextElem(textStr)
appendChildToStack(elemStack, &elem)
case htmltoken.CommentToken:
continue
case htmltoken.DoctypeToken:
tokenErr = errors.New("doctype not supported")
break outer
case htmltoken.ErrorToken:
if iter.Err() == io.EOF {
break outer
}
tokenErr = iter.Err()
break outer
}
}
if tokenErr != nil {
errTextElem := TextElem(tokenErr.Error())
appendChildToStack(elemStack, &errTextElem)
}
rtn := finalizeStack(elemStack)
fixupStyleAttributes(rtn, params, nil)
return rtn
}
View on GitHub (pinned to a4447c1563)
Solutions
- Strip the <!DOCTYPE ...> declaration (and usually <html>/<head>/<body> wrappers) before passing markup to vdom.Bind.
- Configure your template loader to read only the body fragment of HTML documents.
- Convert full documents upstream with an HTML parser (e.g. golang.org/x/net/html) and pass Bind only the extracted fragment.
Example fix
// before
content, _ := os.ReadFile("page.html") // includes <!DOCTYPE html>
elem, err := vdom.Bind(string(content), params)
// after
content, _ := os.ReadFile("page.html")
fragment := stripDoctypeAndBodyExtract(string(content)) // remove <!DOCTYPE ...> prolog
elem, err := vdom.Bind(fragment, params) Defensive patterns
Strategy: validation
Validate before calling
if strings.HasPrefix(strings.TrimSpace(html), "<!DOCTYPE") || strings.HasPrefix(strings.ToLower(strings.TrimSpace(html)), "<!doctype") {
return fmt.Errorf("pass a document fragment, not a full HTML document, to vdom.Bind")
} Try / catch
elem, err := vdom.Bind(html, params)
if err != nil && strings.Contains(err.Error(), "doctype not supported") {
return fmt.Errorf("strip the <!DOCTYPE> prolog before binding: %w", err)
}
if err != nil {
return err
} Prevention
- Feed vdom.Bind fragments, never full HTML documents.
- Strip DOCTYPE and html/head/body wrappers at the template-loader level.
- When exporting from browsers/tools, extract only the body content.
- Add a loader-level test asserting no 'doctype' prefix reaches Bind.
When it happens
Trigger: Passing an entire HTML document including its <!DOCTYPE html> prolog to vdom.Bind instead of just the body/fragment content.
Common situations: Loading .html files saved from browsers or exported documents and feeding them whole into Bind; server-rendering pipelines that hand the full document to the VDOM layer; misconfigured template loaders that do not strip the doctype.
Related errors
- bind tags must be self closing
- TermRef not current
- beginning of file
- procinfo: process not found
- integer overflow
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/a6f88599aa059e30.
Report an issue: GitHub.