chenhg5/cc-connect · error
synthesize: %w
Error message
synthesize: %w
What it means
cc-connect wraps any failure from the configured TTS engine's Synthesize call (which converts reply text into audio data) with the 'synthesize: %w' prefix. The error is a pass-through wrapper: the underlying cause (network, auth, quota, unsupported text) is preserved via %w and should be inspected with errors.Unwrap or errors.As. It is thrown in the engine's TTS reply path before any audio is sent to the platform.
Source
Thrown at core/engine.go:15889
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)
}
slog.Info("tts: audio sent successfully", "platform", p.Name())
return nil
}
// ──────────────────────────────────────────────────────────────
// Bot-to-bot relay
// ──────────────────────────────────────────────────────────────
type platformNameOnly struct {
name string
}
func (p platformNameOnly) Name() string { return p.name }View on GitHub (pinned to 4000b2338a)
Solutions
- Check the wrapped cause with errors.Unwrap(err) or %v of the error to see the provider-specific failure
- Verify TTS provider credentials/endpoint in the [tts] section of config.toml
- Test the TTS provider directly (curl / SDK sample) to rule out outage or quota limits
- Check network egress/proxy settings on the host running cc-connect
- Retry — transient network or rate-limit failures resolve on their own
Example fix
// before
if err != nil {
return fmt.Errorf("synthesize: %w", err)
}
// after
if err != nil {
if errors.Is(err, context.Canceled) {
return err // don't log user-initiated cancellation as failure
}
slog.Warn("tts: synthesis failed, falling back to text reply", "error", err)
return fmt.Errorf("synthesize: %w", err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// before enabling TTS, verify provider works
if e.tts != nil && e.tts.TTS != nil {
if _, _, err := e.tts.TTS.Synthesize(ctx, "ping", opts); err != nil {
slog.Warn("tts provider unavailable, disabling TTS", "error", err)
}
} Type guard
func ttsAvailable(e *Engine) bool {
return e != nil && e.tts != nil && e.tts.TTS != nil
} Try / catch
if err != nil {
var ctxErr error
switch {
case errors.Is(err, context.Canceled), errors.Is(err, context.DeadlineExceeded):
return err // expected during shutdown
default:
slog.Error("tts synthesize failed", "cause", errors.Unwrap(err))
return fmt.Errorf("synthesize: %w", err)
}
_ = ctxErr
} Prevention
- Smoke-test the TTS provider at startup and degrade to text replies on failure
- Keep TTS credentials and endpoint in config.toml under version-controlled review
- Set a sane Synthesize timeout shorter than the user-facing reply deadline
- Monitor provider quotas before they exhaust
When it happens
Trigger: A message reply triggers text-to-speech (e.tts configured) and e.tts.TTS.Synthesize(e.ctx, StripMarkdown(text), opts) returns a non-nil error — e.g. the TTS provider API is unreachable, credentials are invalid, the text exceeds provider limits, or the context is cancelled mid-request.
Common situations: Misconfigured TTS provider credentials in config.toml; TTS service outage or rate limiting; text length exceeding the provider's max input; network egress blocked in the deployment environment; e.ctx cancelled because the user stopped the bot.
Related errors
- platform %s does not support audio sending
- send audio: %w
- openai tts: create request: %w
- openai tts: request: %w
- openai tts API %d: %s
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/4c8b64b176d4ff1f.
Report an issue: GitHub.