fyne-io/fyne · error
string lengths over 1<<15 not yet supported, got len %d
Error message
string lengths over 1<<15 not yet supported, got len %d
What it means
The binary resource string-pool encoder writes every string with a UTF-16 length prefix that must fit in 16 bits. Strings whose Go byte length has bits above bit 15 set (len(x)>>16 > 0) cannot be represented, so the encoder panics citing the 1<<15 supported limit. The pool holds every string compiled into the APK resources - manifest values, string resources, etc.
Source
Thrown at cmd/fyne/internal/mobile/binres/pool.go:190
}
// MarshalBinary outputs the binary format from a given pool
func (pl *Pool) MarshalBinary() ([]byte, error) {
if pl.IsUTF8() {
return nil, fmt.Errorf("encode utf8 not supported")
}
var (
hdrlen = 28
// indices of string indices
iis = make([]uint32, len(pl.strings))
iislen = len(iis) * 4
// utf16 encoded strings concatenated together
strs []uint16
)
for i, x := range pl.strings {
if len(x)>>16 > 0 {
panic(fmt.Errorf("string lengths over 1<<15 not yet supported, got len %d", len(x)))
}
p := utf16.Encode([]rune(x))
if len(p) == 0 {
strs = append(strs, 0x0000, 0x0000)
} else {
strs = append(strs, uint16(len(p))) // string length (implicitly includes zero terminator to follow)
strs = append(strs, p...)
strs = append(strs, 0) // zero terminated
}
// indices start at zero
if i+1 != len(iis) {
iis[i+1] = uint32(len(strs) * 2) // utf16 byte index
}
}
// check strings is 4-byte aligned, pad with zeros if not.
for x := (len(strs) * 2) % 4; x != 0; x -= 2 {
strs = append(strs, 0x0000)View on GitHub (pinned to 8860ee95c3)
Solutions
- Split the oversized string into multiple shorter resources and join them at runtime
- Move the payload out of resources into a bundled asset file loaded with fyne storage or os.ReadFile
- Shorten generated manifest fields (descriptions, URI lists) to well below 32Ki characters
Example fix
<!-- before (strings.xml) --> <string name="payload">AAAA...65KB-of-base64...==</string> <!-- after --> <string name="payload_1">first 16Ki chars</string> <string name="payload_2">remaining chars</string>
Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight: flag any resource/manifest string that could blow the UTF-16 length prefix.
const maxStringLen = 1 << 15 // conservative: the pool writes a uint16 length
func tooLong(s string) bool { return len([]rune(s)) >= maxStringLen }
for name, val := range stringResources {
if tooLong(val) { return fmt.Errorf("resource %s exceeds %d chars; split it or move to an asset", name, maxStringLen) }
} Prevention
- Never paste base64 blobs or keys into strings.xml; bundle them as asset files
- Add a CI length check on generated resources before 'fyne package'
- Split large generated text into chunks under ~16Ki characters each
When it happens
Trigger: Any single string at or beyond the length limit while packaging for Android: a giant label/description, a huge deep-link or scheme list in AndroidManifest.xml, or one enormous strings.xml entry.
Common situations: Base64 blobs, API keys or certificates pasted into string resources; concatenated locale text generated by scripts; manifests with embedded data payloads.
Related errors
- encountered empty values slice
- unhandled token type: %T %+v
- TODO only know how to handle DataIntDec type here
- unsupported GOARCH:
- unsupported architecture:
AI-assisted analysis of fyne-io/fyne@8860ee95c3 (2026-08-15).
Data as JSON: /api/errors/ad8d680c013ed258.
Report an issue: GitHub.