sipeed/picoclaw · error

media store not configured

Error message

media store not configured

What it means

Returned by tts.SynthesizeAndStore when the media.MediaStore argument is nil — the media subsystem was not wired into the TTS call path. Synthesis is skipped entirely; nothing is written to disk or registered.

Source

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

	}
	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)
	if err != nil {
		return "", fmt.Errorf("failed to create media temp dir: %w", err)
	}

View on GitHub (pinned to 49183d7e8d)

Solutions

  1. Initialize the media store at startup and pass the same instance used by other media features
  2. Guard call sites: skip TTS when the store is nil and log why
  3. In tests, use an in-memory store implementation instead of nil

Example fix

// before
ref, err := tts.SynthesizeAndStore(ctx, p, nil, text, name, ch, id)
// after
if store == nil {
    return ``, errors.New(`media store unavailable; skipping tts`)
}
ref, err := tts.SynthesizeAndStore(ctx, p, store, text, name, ch, id)
Defensive patterns

Strategy: validation

Validate before calling

if store == nil {
    return errors.New(`media store not initialized; tts output cannot be registered`)
}

Type guard

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

Try / catch

if err != nil && isNotConfigured(err) {
    // wiring bug at the call site: skip tts and alert, no retry will help
}

Prevention

When it happens

Trigger: Calling SynthesizeAndStore with a nil store handle: the media store was never initialized, or a new call site forgot to pass it.

Common situations: New integrations adding TTS to another channel without plumbing the media store; tests that stub the store as nil.

Related errors


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