chenhg5/cc-connect · warning
text exceeds max_text_len (%d > %d)
Error message
text exceeds max_text_len (%d > %d)
What it means
When TTS is configured, synthesizeAndSendTTS enforces an optional per-request text length limit: if tts.max_text_len > 0 and the reply text has more runes than that limit, synthesis is refused with this error naming both the actual and maximum rune counts.
Source
Thrown at core/engine.go:15875
// sendTTSReply synthesizes fullResponse text and sends audio to the platform.
// Called asynchronously after EventResult; text reply is always sent first.
func (e *Engine) sendTTSReply(p Platform, replyCtx any, text string) {
slog.Debug("tts: sendTTSReply called", "platform", p.Name(), "text_len", len(text))
if err := e.synthesizeAndSendTTS(p, replyCtx, text); err != nil {
slog.Error("tts: voice reply failed", "platform", p.Name(), "error", err)
}
}
func (e *Engine) synthesizeAndSendTTS(p Platform, replyCtx any, text string) error {
if e.tts == nil || !e.tts.Enabled {
return fmt.Errorf("tts is not configured")
}
if e.tts.TTS == nil {
return fmt.Errorf("tts provider is not configured")
}
if e.tts.MaxTextLen > 0 && utf8.RuneCountInString(text) > e.tts.MaxTextLen {
return fmt.Errorf("text exceeds max_text_len (%d > %d)", utf8.RuneCountInString(text), e.tts.MaxTextLen)
}
as, ok := p.(AudioSender)
if !ok {
return fmt.Errorf("platform %s does not support audio sending", p.Name())
}
slog.Info("tts: starting synthesis", "voice", e.tts.Voice, "speed", e.tts.Speed, "text_len", len(text))
opts := TTSSynthesisOpts{
Voice: e.tts.Voice,
LanguageType: e.tts.LanguageType,
Speed: e.tts.Speed,
}
audioData, format, err := e.tts.TTS.Synthesize(e.ctx, StripMarkdown(text), opts)
if err != nil {
return fmt.Errorf("synthesize: %w", err)
}
slog.Info("tts: synthesis successful", "format", format, "audio_size", len(audioData))
if err := as.SendAudio(e.ctx, replyCtx, audioData, format); err != nil {
return fmt.Errorf("send audio: %w", err)View on GitHub (pinned to 4000b2338a)
Solutions
- Increase tts.max_text_len in config.toml (or remove it to disable the cap) and reload
- Truncate or summarize the text to fit within max_text_len before requesting TTS
- Send the long content as a text/file message instead of voice
Example fix
// before (config.toml) [tts] enabled = true max_text_len = 200 // after [tts] enabled = true max_text_len = 2000
Defensive patterns
Strategy: fallback
Validate before calling
if e.TTSMaxTextLen() > 0 && utf8.RuneCountInString(text) > e.TTSMaxTextLen() {
text = truncateRunes(text, e.TTSMaxTextLen())
} Try / catch
if err := e.SynthesizeAndSendTTS(p, replyCtx, text); err != nil {
if strings.Contains(err.Error(), "exceeds max_text_len") {
p.Reply(replyCtx, text) // send as text instead
return
}
return err
} Prevention
- Truncate or summarize long replies before requesting voice synthesis
- Set max_text_len generously or omit it to lift the cap
- Use rune counts (utf8.RuneCountInString), not byte length, when pre-checking
- Watch for repeated failures with long agent outputs and switch those to text replies
When it happens
Trigger: Requesting a voice reply for text whose UTF-8 rune count exceeds tts.max_text_len, e.g. asking the agent to speak a long code answer when max_text_len = 500.
Common situations: Long agent responses sent as voice; conservative max_text_len values set to control provider cost; multilingual text where users underestimate rune counts.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- hook input exceeds %d bytes
- Content-Length too large: %d
- download exceeds --max-bytes: %d > %d
- tts is not configured
- tts provider is not configured
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/01dc5c8efdff8f42.
Report an issue: GitHub.