openclaw - ✅(Solved) Fix v2026.3.28: CLI validator rejects valid messages.tts.elevenlabs config [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#57314Fetched 2026-04-08 01:51:07
View on GitHub
Comments
1
Participants
2
Timeline
5
Reactions
0
Timeline (top)
closed ×1commented ×1cross-referenced ×1locked ×1

PR fix notes

PR #57953: fix(tts): restore 3.28 schema compatibility and fallback observability

Description (problem / solution / changelog)

Summary

  • Problem: v2026.3.28 introduced a schema/validation mismatch where legacy messages.tts.<provider> and plugins.entries.voice-call.config.tts.<provider> shapes (notably elevenlabs) were rejected even though runtime/docs still treated them as valid.
  • Why it matters: openclaw status, openclaw doctor, and voice-call plugin registration could fail against previously working configurations.
  • What changed:
    • Restored legacy TTS provider-shape compatibility in speech-core config migration/validation.
    • Aligned voice-call plugin TTS schema/docs with tts.providers.<id> plus legacy compatibility handling.
    • Added fallback observability: provider attempt chain and fallback metadata are persisted and surfaced in /tts status, plus telephony fallback warning logs.
    • Added regression tests for legacy config migration/validation and command/status fallback reporting.
  • What did NOT change (scope boundary): this PR does not add per-agent Discord voice assignment behavior or force-provider lock semantics; it focuses on 3.28 schema regression + fallback observability.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #57314
  • Closes #56983
  • Related #46015
  • Related #52186
  • This PR fixes a bug or regression

Cluster Item Coverage

  • #57314 (messages.tts.elevenlabs rejected by CLI validator): Completely addressed.
    • Legacy provider key shape is accepted/migrated again and no longer treated as unrecognized.
  • #56983 (voice-call tts.elevenlabs rejected as unrecognized): Completely addressed.
    • Voice-call TTS config parsing now accepts the documented/legacy shape and aligns with schema behavior.
  • #46015 (silent fallback to Edge in Discord + no visibility): Partially addressed.
    • Addressed: fallback path is now visible via /tts status attempt chain/details and telephony warning logs.
    • Not addressed here: per-agent Discord voice support and hard prevention of provider fallback behavior.
  • #52186 (ElevenLabs call observed but OpenAI voice playback): Partially addressed.
    • Addressed: fallback attempts/selected provider are now surfaced for diagnosis.
    • Not addressed here: enforcing provider stickiness or changing provider-selection policy.

Root Cause / Regression History (if applicable)

  • Root cause: 3.28 schema path drift between accepted config surfaces and runtime/documented shapes for TTS provider config, especially legacy direct provider keys.
  • Missing detection / guardrail: insufficient regression coverage for legacy shape acceptance across CLI validation + plugin validation surfaces.
  • Prior context (git blame, prior PR, issue, or refactor if known): surfaced after the 3.24 -> 3.28 upgrade reports in #57314 and #56983.
  • Why this regressed now: schema tightening/normalization was not mirrored by compatibility migration at all validation entry points.
  • If unknown, what was ruled out: ruled out runtime provider registration itself as sole cause (runtime synthesis still worked in affected reports).

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file:
    • src/config/legacy-migrate.test.ts
    • src/config/config-misc.test.ts
    • src/config/config.plugin-validation.test.ts
    • src/config/schema.test.ts
    • src/auto-reply/reply/commands-tts.test.ts
    • extensions/voice-call/src/config.test.ts
    • extensions/voice-call/src/telephony-tts.test.ts
  • Scenario the test should lock in: legacy provider-key configs remain accepted/migrated; fallback attempt/final provider visibility remains available in status/logs.
  • Why this is the smallest reliable guardrail: it covers both config-surface compatibility and user-visible fallback diagnostics where regressions were reported.
  • Existing test that already covers this (if any): expanded from existing config + voice-call test suites.
  • If no new test is added, why not: N/A.

User-visible / Behavior Changes

  • openclaw status / validation no longer reject legacy messages.tts.<provider> shapes like messages.tts.elevenlabs.
  • Voice-call plugin no longer rejects legacy plugins.entries.voice-call.config.tts.<provider> keys like tts.elevenlabs.
  • /tts status now shows fallback chain/details from the latest attempt.
  • Voice-call telephony emits explicit warning logs when fallback provider is used.

Diagram (if applicable)

Before:
legacy tts provider keys -> schema rejects key -> status/doctor/plugin fail

After:
legacy tts provider keys -> compatibility migration/acceptance -> validation passes -> runtime + diagnostics available

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (No)
  • New/changed network calls? (No)
  • Command/tool execution surface changed? (No)
  • Data access scope changed? (No)
  • If any Yes, explain risk + mitigation: N/A

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node 22+/pnpm workspace
  • Model/provider: ElevenLabs/OpenAI/Microsoft TTS paths
  • Integration/channel (if any): CLI + voice-call
  • Relevant config (redacted): messages.tts.* and plugins.entries.voice-call.config.tts.*

Steps

  1. Configure legacy direct provider keys under messages.tts and voice-call plugin tts.
  2. Run validation/status flows and voice-call plugin registration.
  3. Trigger fallback path and inspect /tts status and voice-call logs.

Expected

  • Legacy shapes accepted.
  • Voice-call plugin registers.
  • Fallback chain/details visible.

Actual

  • Matched expected in targeted validation/tests.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

  • Verified scenarios:
    • Targeted tests for config migration/schema/plugin validation and fallback observability.
  • Edge cases checked:
    • Success and failure fallback attempt reporting.
    • Voice-call telephony fallback warning logging.
  • What you did not verify:
    • Full pnpm check / full-suite e2e outside touched TTS surfaces.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No)
  • Migration needed? (No)
  • If yes, exact upgrade steps: N/A

Risks and Mitigations

  • Risk: compatibility behavior differs across obscure provider-key variants.
    • Mitigation: compatibility normalization + targeted regression coverage across config and plugin validation.
  • Risk: fallback visibility could be noisy.
    • Mitigation: scoped to status output and explicit warning logs only when fallback occurs.

Changed files

  • apps/macos/Sources/OpenClaw/HostEnvSecurityPolicy.generated.swift (modified, +0/-1)
  • docs/gateway/doctor.md (modified, +4/-0)
  • docs/plugins/voice-call.md (modified, +21/-11)
  • docs/tools/tts.md (modified, +4/-0)
  • docs/tts.md (modified, +4/-0)
  • extensions/speech-core/src/tts.ts (modified, +69/-7)
  • extensions/voice-call/index.ts (modified, +7/-7)
  • extensions/voice-call/openclaw.plugin.json (modified, +162/-110)
  • extensions/voice-call/src/runtime.ts (modified, +1/-0)
  • extensions/voice-call/src/telephony-tts.test.ts (modified, +24/-1)
  • extensions/voice-call/src/telephony-tts.ts (modified, +16/-1)
  • src/auto-reply/reply/commands-tts.test.ts (added, +120/-0)
  • src/auto-reply/reply/commands-tts.ts (modified, +12/-0)
  • src/config/config-misc.test.ts (modified, +75/-0)
  • src/config/config.plugin-validation.test.ts (modified, +75/-5)
  • src/config/legacy-migrate.test.ts (modified, +124/-0)
  • src/config/legacy.migrations.runtime.ts (modified, +92/-7)
  • src/infra/host-env-security-policy.json (modified, +0/-1)
  • src/plugins/contracts/tts.contract.test.ts (modified, +25/-0)

Code Example

Config invalid
- messages.tts: Unrecognized key: "elevenlabs"

---

{
  "messages": {
    "tts": {
      "provider": "elevenlabs",
      "elevenlabs": {
        "apiKey": "REDACTED",
        "voiceId": "w6INrsHCejnExFzTH8Nm",
        "modelId": "eleven_multilingual_v2",
        "voiceSettings": {
          "stability": 0.35,
          "similarityBoost": 0.85,
          "style": 0,
          "useSpeakerBoost": true
        }
      }
    }
  }
}
RAW_BUFFERClick to expand / collapse

Bug

After updating from v2026.3.24 to v2026.3.28, openclaw status and openclaw doctor reject the config with:

Config invalid
- messages.tts: Unrecognized key: "elevenlabs"

However:

  1. config.schema.lookup at messages.tts.elevenlabs confirms it's a valid key with children (apiKey, voiceId, modelId, voiceSettings, etc.)
  2. The gateway process itself starts and runs fine with this config
  3. TTS works correctly at runtime

Config (redacted)

{
  "messages": {
    "tts": {
      "provider": "elevenlabs",
      "elevenlabs": {
        "apiKey": "REDACTED",
        "voiceId": "w6INrsHCejnExFzTH8Nm",
        "modelId": "eleven_multilingual_v2",
        "voiceSettings": {
          "stability": 0.35,
          "similarityBoost": 0.85,
          "style": 0,
          "useSpeakerBoost": true
        }
      }
    }
  }
}

Impact

  • openclaw status exits with code 1 (can't check status)
  • openclaw doctor runs in "best-effort" mode and offers to strip the elevenlabs config via --fix
  • Running doctor --fix would likely remove working TTS configuration

Environment

  • Version: v2026.3.28 (upgraded from v2026.3.24)
  • OS: macOS (Darwin 25.3.0 arm64)
  • Node: v25.8.1
  • Install: npm global

extent analysis

Fix Plan

To resolve the issue, we need to update the configuration validation to recognize the "elevenlabs" key under "messages.tts".

Here are the steps:

  • Update the config.schema.json file to include the "elevenlabs" key as a valid property under "messages.tts".
  • Use the following schema definition:
{
  "type": "object",
  "properties": {
    "messages": {
      "type": "object",
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!      "properties": {
        "tts": {
          "type": "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!          "object",
          "properties": {
            "provider!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING