fyne-io/fyne · error
unhandled token type: %T %+v
Error message
unhandled token type: %T %+v
What it means
Thrown by the Android binary-XML (AXML) compiler in fyne's vendored mobile tool. When 'fyne package -os android' compiles AndroidManifest.xml, binres walks encoding/xml tokens: it handles StartElement, EndElement and CharData, and discards Comment/ProcInst. Any other token type - in practice an xml.Directive such as '<!DOCTYPE ...>' - reaches the default branch and panics with the token's Go type and value.
Source
Thrown at cmd/fyne/internal/mobile/binres/binres.go:588
}
n := len(bx.stack)
var el *Element
el, bx.stack = bx.stack[n-1], bx.stack[:n-1]
if el.end != nil {
return fmt.Errorf("element end already exists")
}
el.end = &ElementEnd{
NodeHeader: NodeHeader{
LineNumber: uint32(line),
Comment: NoEntry,
},
NS: el.NS,
Name: el.Name,
}
case xml.Comment, xml.ProcInst:
// discard
default:
panic(fmt.Errorf("unhandled token type: %T %+v", tkn, tkn))
}
return nil
}
// addAttributes encodes the attributes of tkn and adds them to el.
// Any attributes which were not already present in Pool are added to it.
func addAttributes(tkn xml.StartElement, bx *XML, line int, pool *Pool, el *Element, tbl *Table) error {
for _, attr := range tkn.Attr {
if (attr.Name.Space == "xmlns" && attr.Name.Local == "tools") || attr.Name.Space == toolsSchema {
continue // TODO can tbl be queried for schemas to determine validity instead?
}
if attr.Name.Space == "xmlns" && attr.Name.Local == "android" {
if bx.Namespace != nil {
return fmt.Errorf("multiple declarations of xmlns:android encountered")
}
bx.Namespace = &Namespace{
NodeHeader: NodeHeader{View on GitHub (pinned to 8860ee95c3)
Solutions
- Remove the '<!DOCTYPE ...>' (or any other '<!...>') directive from AndroidManifest.xml - Android packaging does not need it
- Re-serialize the manifest with xmllint or an editor so no directive tokens remain, then re-run fyne package
- Upgrade fyne to a release that tolerates xml.Directive, or patch the default case in binres.go to discard xml.Directive like xml.Comment
Example fix
// before (AndroidManifest.xml) <!DOCTYPE manifest PUBLIC "-//Android//DTD Android 3.0//EN" "http://schemas.android.com/apk/res/android"> <manifest ...> // after <manifest ...>
Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight: reject manifests containing XML directives before packaging.
dec := xml.NewDecoder(manifestFile)
for {
tkn, err := dec.Token()
if err == io.EOF { break }
if err != nil { return err }
if _, ok := tkn.(xml.Directive); ok {
return fmt.Errorf("AndroidManifest.xml contains an XML directive; remove it before packaging")
}
} Prevention
- Keep custom AndroidManifest.xml free of DOCTYPE and other directives; Android does not use them
- Re-serialize pasted manifests through xmllint before committing
- Run 'xmllint --noout AndroidManifest.xml' in CI before the fyne package step
When it happens
Trigger: Running 'fyne package -os android' (or calling binres XML build) against a custom AndroidManifest.xml that contains an XML directive: a '<!DOCTYPE manifest ...>' declaration or '<!ELEMENT>'/'<!ENTITY>' lines produced by an XML editor or copied from an Android Studio project.
Common situations: Custom manifests pasted from tutorials or other projects that carry a DOCTYPE; manifests processed by XML tooling that emits directives; template files reused across projects.
Related errors
- encountered empty values slice
- TODO only know how to handle DataIntDec type here
- string lengths over 1<<15 not yet supported, got len %d
- unknown GOARCH: %q
- unsupported GOARCH:
AI-assisted analysis of fyne-io/fyne@8860ee95c3 (2026-08-15).
Data as JSON: /api/errors/2591801d734b58e9.
Report an issue: GitHub.