sipeed/picoclaw · error

tts provider is not configured

Error message

tts provider is not configured

What it means

Returned by tts.SynthesizeAndStore when the provider argument is nil. The provider normally comes from DetectTTS(cfg), which returns nil when cfg is nil, Voice.TTSModelName is unset or unresolvable, and no ModelList entry both contains 'tts' in its model name and has an API key. This is a configuration/startup error, not a runtime fault.

Source

Thrown at pkg/audio/tts/tts.go:99

				return provider
			}
		}
	}
	return nil
}

// SynthesizeAndStore synthesizes text to speech and registers it in the media store, returning the media reference.
func SynthesizeAndStore(
	ctx context.Context,
	provider TTSProvider,
	store media.MediaStore,
	text string,
	filename string,
	channel string,
	chatID string,
) (string, error) {
	if provider == nil {
		return "", fmt.Errorf("tts provider is not configured")
	}
	if store == nil {
		return "", fmt.Errorf("media store not configured")
	}
	if channel == "" || chatID == "" {
		return "", fmt.Errorf("no target channel/chat available")
	}
	if strings.TrimSpace(text) == "" {
		return "", fmt.Errorf("text is required")
	}

	stream, err := provider.Synthesize(ctx, text)
	if err != nil {
		return "", fmt.Errorf("tts synthesize failed: %w", err)
	}
	defer stream.Close()

	err = os.MkdirAll(media.TempDir(), 0o700)

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Set voice.tts_model_name to a configured model that has an api_key
  2. Or add a ModelList entry whose model name contains 'tts' (e.g. tts-1, mimo-v2-tts) with its api_key
  3. Check DetectTTS(cfg) for nil right after startup and log a clear message
  4. Skip TTS-dependent features when the provider is nil instead of calling SynthesizeAndStore

Example fix

// before
ref, err := tts.SynthesizeAndStore(ctx, provider, store, text, name, ch, id)
// after
if provider == nil {
    logger.WarnF(`tts disabled: no provider detected`, nil)
    return ``, nil
}
ref, err := tts.SynthesizeAndStore(ctx, provider, store, text, name, ch, id)
Defensive patterns

Strategy: validation

Validate before calling

provider := tts.DetectTTS(cfg)
if provider == nil {
    return errors.New(`no tts provider detected: set voice.tts_model_name or add a model containing 'tts' with an api_key`)
}

Type guard

func isNotConfigured(err error) bool {
    return err != nil && strings.Contains(err.Error(), `not configured`)
}

Try / catch

if err != nil && isNotConfigured(err) {
    // disable voice output for this session; do not retry until configuration changes
}

Prevention

When it happens

Trigger: Voice features invoked with no TTS model configured; TTSModelName pointing at a model whose APIKey() is empty (providerFromModelConfig returns nil); model entries renamed so the 'tts' substring match in DetectTTS fails.

Common situations: Fresh installs without TTS config; renaming model entries; forgetting the api_key on the TTS model entry.

Related errors


AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15). Data as JSON: /api/errors/7518802bbe03804b. Report an issue: GitHub.