openclaw - 💡(How to fix) Fix [Bug]: 2026.3.28 removes messages.tts.edge from Zod schema without auto-migration, breaking existing Edge TTS configs [2 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#56933Fetched 2026-04-08 01:45:49
View on GitHub
Comments
2
Participants
2
Timeline
4
Reactions
8
Author
Participants
Timeline (top)
commented ×2closed ×1locked ×1

Upgrading from 2026.3.24 to 2026.3.28 causes Gateway to reject existing messages.tts.edge config with:

messages.tts: Unrecognized key: "edge"

This is a breaking change that was listed under "Changes" (not "Breaking") in the 2026.3.28 changelog:

Config/TTS: auto-migrate legacy speech config on normal reads and secret resolution, keep legacy diagnostics for Doctor, and remove regular-mode runtime fallback for old bundled tts.<provider> API-key shapes.

Root Cause

Root Cause (code-verified)

Fix Action

Fix / Workaround

  1. Have working Edge TTS config in 2026.3.24:
{
  "messages": {
    "tts": {
      "provider": "edge",
      "edge": {
        "voice": "en-US-JennyNeural",
        "lang": "en-US",
        "outputFormat": "ogg-24khz-16bit-mono-opus"
      }
    }
  }
}
  1. Upgrade to 2026.3.28
  2. Gateway refuses to start: messages.tts: Unrecognized key: "edge"
  3. openclaw doctor --fix does not fix this

Code Example

messages.tts: Unrecognized key: "edge"

---

const TtsConfigSchema = z.object({
  auto, enabled, mode, provider, summaryModel,
  modelOverrides: { ... },
  elevenlabs: { ... },
  openai: { ... },
  edge: TtsMicrosoftConfigSchema,    // ← present
  microsoft: TtsMicrosoftConfigSchema, // ← present
  prefsPath, maxTextLength, timeoutMs
}).strict().optional();

---

const TtsConfigSchema = z.object({
  auto, enabled, mode, provider, summaryModel,
  modelOverrides: { ... },
  providers: z.record(z.string(), TtsProviderConfigSchema).optional(),  // ← new
  prefsPath, maxTextLength, timeoutMs
}).strict().optional();

---

{
  "messages": {
    "tts": {
      "auto": "off",
      "mode": "final",
      "provider": "edge",
      "providers": {
        "edge": {
          "voice": "en-US-JennyNeural",
          "lang": "en-US",
          "outputFormat": "ogg-24khz-16bit-mono-opus",
          "pitch": "+0Hz",
          "rate": "+0%",
          "volume": "+0%",
          "timeoutMs": 30000
        }
      }
    }
  }
}

---

{
  "messages": {
    "tts": {
      "provider": "edge",
      "edge": {
        "voice": "en-US-JennyNeural",
        "lang": "en-US",
        "outputFormat": "ogg-24khz-16bit-mono-opus"
      }
    }
  }
}
RAW_BUFFERClick to expand / collapse

Summary

Upgrading from 2026.3.24 to 2026.3.28 causes Gateway to reject existing messages.tts.edge config with:

messages.tts: Unrecognized key: "edge"

This is a breaking change that was listed under "Changes" (not "Breaking") in the 2026.3.28 changelog:

Config/TTS: auto-migrate legacy speech config on normal reads and secret resolution, keep legacy diagnostics for Doctor, and remove regular-mode runtime fallback for old bundled tts.<provider> API-key shapes.

Root Cause (code-verified)

2026.3.24 TtsConfigSchema (zod-schema.agent-runtime-DNndkpI8.js:328):

const TtsConfigSchema = z.object({
  auto, enabled, mode, provider, summaryModel,
  modelOverrides: { ... },
  elevenlabs: { ... },
  openai: { ... },
  edge: TtsMicrosoftConfigSchema,    // ← present
  microsoft: TtsMicrosoftConfigSchema, // ← present
  prefsPath, maxTextLength, timeoutMs
}).strict().optional();

2026.3.28 TtsConfigSchema (zod-schema.core-CGoKjdG2.js:278):

const TtsConfigSchema = z.object({
  auto, enabled, mode, provider, summaryModel,
  modelOverrides: { ... },
  providers: z.record(z.string(), TtsProviderConfigSchema).optional(),  // ← new
  prefsPath, maxTextLength, timeoutMs
}).strict().optional();

edge, microsoft, elevenlabs, and openai sub-objects were removed from the Zod schema and replaced with a generic providers record. The schema uses .strict(), so any unrecognized key causes a hard validation failure.

Note: The JSON Schema export in bundled voice-call plugin metadata (chat-meta-xAV2SRO1.js:14476) still includes edge as a property — but this is the voice-call plugin's TTS schema, not the main messages.tts schema. The Zod schema (which is used for actual config validation) does not include edge.

Auto-migration gap

The changelog says "auto-migrate legacy speech config on normal reads", but the auto-migration (env-D1ktUnAV.js, applyLegacyMigrations) only handles messages.tts.enabled → messages.tts.auto. It does not migrate messages.tts.edgemessages.tts.providers.edge.

Expected new config format

Based on the new schema, the correct format should be:

{
  "messages": {
    "tts": {
      "auto": "off",
      "mode": "final",
      "provider": "edge",
      "providers": {
        "edge": {
          "voice": "en-US-JennyNeural",
          "lang": "en-US",
          "outputFormat": "ogg-24khz-16bit-mono-opus",
          "pitch": "+0Hz",
          "rate": "+0%",
          "volume": "+0%",
          "timeoutMs": 30000
        }
      }
    }
  }
}

Steps to Reproduce

  1. Have working Edge TTS config in 2026.3.24:
{
  "messages": {
    "tts": {
      "provider": "edge",
      "edge": {
        "voice": "en-US-JennyNeural",
        "lang": "en-US",
        "outputFormat": "ogg-24khz-16bit-mono-opus"
      }
    }
  }
}
  1. Upgrade to 2026.3.28
  2. Gateway refuses to start: messages.tts: Unrecognized key: "edge"
  3. openclaw doctor --fix does not fix this

Suggested Fix

Add auto-migration in applyLegacyMigrations() to move messages.tts.<provider> sub-objects into messages.tts.providers.<provider> for all four affected providers (edge, microsoft, elevenlabs, openai).

Environment

  • OpenClaw: 2026.3.28 (reverted to 2026.3.24)
  • macOS arm64, Node 22.22.1

Related

  • #56220 (same symptom reported by another user)

extent analysis

Fix Plan

To resolve the issue, we need to update the applyLegacyMigrations() function to auto-migrate the legacy speech config. Here are the steps:

  1. Update applyLegacyMigrations():
    • Add a new migration to move messages.tts.<provider> sub-objects into messages.tts.providers.<provider> for all four affected providers (edge, microsoft, elevenlabs, openai).
  2. Example code:

const migrateLegacyTtsConfig = (config) => { const providers = ['edge', 'microsoft', 'elevenlabs', 'openai']; providers.forEach((provider) => { if (config.messages && config.messages.tts && config.messages.tts[provider]) { if (!config.messages.tts.providers) { config.messages.tts.providers = {}; } config.messages.tts.providers[provider] = config.messages.tts[provider]; delete config.messages.tts[provider]; } }); return config; };

3. **Integrate with `applyLegacyMigrations()`**:
   * Call `migrateLegacyTtsConfig()` within `applyLegacyMigrations()` to apply the migration.

### Verification
To verify that the fix worked:

1. **Apply the migration**: Run `openclaw doctor --fix` to apply the migration.
2. **Check the config**: Verify that the `messages.tts` config has been updated to the new format.
3. **Restart the Gateway**: Restart the Gateway to ensure it starts successfully with the updated config.

### Extra Tips
* Make sure to test the migration thoroughly to avoid any data loss or corruption.
* Consider adding additional logging or monitoring to detect any issues with the migration.
* Review the changelog and documentation to ensure that the new config format is correctly documented.

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