openclaw - ✅(Solved) Fix voice-call realtime: "Realtime voice provider \"openai\" is not registered" on startup — load-order bug similar to #60936 but on realtime voice path [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#80483Fetched 2026-05-11 03:14:13
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
2
Author
Timeline (top)
cross-referenced ×3commented ×1

In 2026.5.7, enabling voice-call.realtime with provider: "openai" (and OpenAI not auto-loaded for other reasons) causes the voice-call runtime to fail with:

[voice-call] Failed to start runtime: Realtime voice provider "openai" is not registered

The voice-call plugin's runtime initializes at gateway startup. At that point the bundled openai plugin has activation.onStartup: false and has not been loaded — so its realtimeVoiceProviders contract is not in the active runtime registry. The capability resolver in resolvePluginCapabilityProviders does not eagerly load the missing provider plugin in this case, and resolveConfiguredRealtimeVoiceProvider throws missing-configured-provider.

This is functionally the same shape of failure as #60936 (closed by #61224), but on the realtime voice code path instead of the realtime transcription path. PR #61224 made the webhook server use fullConfig for transcription provider resolution; the realtime voice resolver appears to have the same root cause (capability lookup at startup before the provider plugin has loaded) and the existing fix doesn't cover it.

Error Message

  • Error log: [voice-call] Failed to start runtime: Realtime voice provider "openai" is not registered

Root Cause

This is functionally the same shape of failure as #60936 (closed by #61224), but on the realtime voice code path instead of the realtime transcription path. PR #61224 made the webhook server use fullConfig for transcription provider resolution; the realtime voice resolver appears to have the same root cause (capability lookup at startup before the provider plugin has loaded) and the existing fix doesn't cover it.

Fix Action

Workaround

Patch the bundled openai plugin manifest to set activation.onStartup: true:

python3 - <<'PY'
import json
p = '/path/to/openclaw/dist/extensions/openai/openclaw.plugin.json'
d = json.load(open(p))
d['activation']['onStartup'] = True
json.dump(d, open(p, 'w'), indent=2)
PY

After this, gateway startup shows 4 plugins: google, memory-core, openai, voice-call and [voice-call] Realtime voice provider: openai — works.

This survives until the next openclaw update, after which it must be re-applied.

PR fix notes

PR #80486: fix(capability-provider): merge manifest realtime voice/transcription providers when active registry is partial

Description (problem / solution / changelog)

Summary

When the active runtime plugin registry has some realtime-voice (or realtime-transcription) providers but not the one the configured plugin (e.g. voice-call) actually asks for — because that provider's host plugin hasn't been eagerly loaded yet — resolvePluginCapabilityProviders short-circuits to the active set and skips merging in manifest-declared bundled-compat providers. The realtime resolver then throws "Realtime voice provider 'X' is not registered" at startup.

Concrete repro: enable voice-call with realtime.enabled: true and realtime.provider: "openai", but with the agent on xai/grok-4 and no OpenAI model in the catalog. At gateway startup, google's plugin loads (it's pulled in by the memory boot path because it provides memoryEmbeddingProviders: ["gemini"]) and registers realtimeVoiceProviders: ["google"]. openai's bundled plugin doesn't load (activation.onStartup: false and no eager-load trigger). When voice-call's runtime asks for the openai realtime provider, the lookup sees active=[google], treats it as a complete result, and fails. See #80483 for the full trace.

The same shape of problem was fixed for realtime transcription in #61224 by passing fullConfig to the webhook server, but the realtime-voice path is gated by a separate lever: shouldMergeManifestProvidersWhenActive, which only returned true for image/video/music generation. This PR extends it to cover realtime-voice and realtime-transcription so the manifest-declared bundled-compat providers are still resolved when the active registry contains only a partial set.

Changes

  • src/plugins/capability-provider-runtime.ts: add realtimeVoiceProviders and realtimeTranscriptionProviders to shouldMergeManifestProvidersWhenActive, with a comment pointing at the bug.
  • src/plugins/capability-provider-runtime.test.ts: add a regression test that mirrors the existing image-generation merge test for realtime voice — active=[google], manifest=[google, openai], config requests both; expects [google, openai] in the result.
  • CHANGELOG.md: Unreleased Fixes entry.

Test plan

  • pnpm exec vitest run --config test/vitest/vitest.plugins.config.ts src/plugins/capability-provider-runtime.test.ts — 40/40 pass.
  • Manual end-to-end: with this fix the gateway loads voice-call's realtime runtime successfully against openai even when only google is in the active registry at startup.

Fixes #80483.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/plugins/capability-provider-runtime.test.ts (modified, +50/-0)
  • src/plugins/capability-provider-runtime.ts (modified, +9/-1)

Code Example

[voice-call] Failed to start runtime: Realtime voice provider "openai" is not registered

---

{
     "plugins": {
       "allow": ["voice-call", "openai", "memory-core", "google", "xai"],
       "entries": {
         "openai": { "enabled": true },
         "voice-call": {
           "enabled": true,
           "config": {
             "provider": "twilio",
             "twilio": { "accountSid": "...", "authToken": "..." },
             "fromNumber": "+1XXXXXXXXXX",
             "inboundPolicy": "open",
             "tunnel": { "provider": "ngrok" },
             "realtime": {
               "enabled": true,
               "provider": "openai",
               "providers": {
                 "openai": { "apiKey": "sk-proj-...", "model": "gpt-4o-realtime-preview" }
               }
             }
           }
         }
       }
     }
   }

---

[plugins] loading google from .../extensions/google/index.js
[plugins] loading memory-core from .../extensions/memory-core/index.js
[plugins] loading voice-call from ~/.openclaw/npm/.../voice-call/dist/index.js
[plugins] loaded 3 plugin(s) (3 attempted) in 1170.0ms
[gateway] http server listening (3 plugins: google, memory-core, voice-call; 1.7s)
[plugins] [voice-call] Failed to start runtime: Realtime voice provider "openai" is not registered

---

python3 - <<'PY'
import json
p = '/path/to/openclaw/dist/extensions/openai/openclaw.plugin.json'
d = json.load(open(p))
d['activation']['onStartup'] = True
json.dump(d, open(p, 'w'), indent=2)
PY

---

const coldEntries = (loadedRegistry ? void 0 : resolveRuntimePluginRegistry(params.loadOptions))?.[params.key] ?? [];
RAW_BUFFERClick to expand / collapse

Bug type

Regression (worked before, now fails)

Beta release blocker

Yes (silent loss of inbound voice-call functionality whenever realtime.provider is a plugin that isn't already loaded)

Summary

In 2026.5.7, enabling voice-call.realtime with provider: "openai" (and OpenAI not auto-loaded for other reasons) causes the voice-call runtime to fail with:

[voice-call] Failed to start runtime: Realtime voice provider "openai" is not registered

The voice-call plugin's runtime initializes at gateway startup. At that point the bundled openai plugin has activation.onStartup: false and has not been loaded — so its realtimeVoiceProviders contract is not in the active runtime registry. The capability resolver in resolvePluginCapabilityProviders does not eagerly load the missing provider plugin in this case, and resolveConfiguredRealtimeVoiceProvider throws missing-configured-provider.

This is functionally the same shape of failure as #60936 (closed by #61224), but on the realtime voice code path instead of the realtime transcription path. PR #61224 made the webhook server use fullConfig for transcription provider resolution; the realtime voice resolver appears to have the same root cause (capability lookup at startup before the provider plugin has loaded) and the existing fix doesn't cover it.

Steps to reproduce

  1. Fresh install of [email protected] on macOS.
  2. Configure voice-call for Twilio + ngrok with realtime enabled:
    {
      "plugins": {
        "allow": ["voice-call", "openai", "memory-core", "google", "xai"],
        "entries": {
          "openai": { "enabled": true },
          "voice-call": {
            "enabled": true,
            "config": {
              "provider": "twilio",
              "twilio": { "accountSid": "...", "authToken": "..." },
              "fromNumber": "+1XXXXXXXXXX",
              "inboundPolicy": "open",
              "tunnel": { "provider": "ngrok" },
              "realtime": {
                "enabled": true,
                "provider": "openai",
                "providers": {
                  "openai": { "apiKey": "sk-proj-...", "model": "gpt-4o-realtime-preview" }
                }
              }
            }
          }
        }
      }
    }
  3. Agent's primary model is xai/grok-4 (no OpenAI model in catalog, so OpenAI is not auto-enabled by the model-driven path).
  4. openclaw gateway restart
  5. Place a call to the Twilio number.

Expected behavior

Inbound call connects to OpenAI realtime voice and the agent responds.

Actual behavior

  • Gateway startup log: http server listening (3 plugins: google, memory-core, voice-call; ...)
  • Error log: [voice-call] Failed to start runtime: Realtime voice provider "openai" is not registered
  • Inbound call returns just <Pause length="30"/> TwiML → 30 seconds of dead air → Twilio gives up.
  • openclaw voicecall setup reports OK for all checks including mode: Realtime voice enabled (openai), because that probe is purely config-validity and doesn't query the active runtime registry. So voicecall setup does not surface the failure.

OpenClaw version

2026.5.7

Operating system

macOS 26.3.1 (arm64), Node 22.14.0

Install method

pnpm (global install at /usr/local/.../node_modules/openclaw)

Model

xAI Grok-4 as the agent's primary model; OpenAI used only for realtime voice.

Provider / routing chain

twilio -> ngrok -> openclaw/voice-call -> openai realtime

Additional provider/model setup details

openai plugin is enabled-in-config and present in plugins.allow. Its manifest declares activation.onStartup: false and contracts.realtimeVoiceProviders: ["openai"].

Logs, screenshots, and evidence

Trace-level gateway log around startup:

[plugins] loading google from .../extensions/google/index.js
[plugins] loading memory-core from .../extensions/memory-core/index.js
[plugins] loading voice-call from ~/.openclaw/npm/.../voice-call/dist/index.js
[plugins] loaded 3 plugin(s) (3 attempted) in 1170.0ms
[gateway] http server listening (3 plugins: google, memory-core, voice-call; 1.7s)
[plugins] [voice-call] Failed to start runtime: Realtime voice provider "openai" is not registered

Note: 3 plugins attempted — the openai plugin is never even attempted at startup, despite being enabled in config and present in plugins.allow. google and memory-core are attempted because: memory-core is the memory slot (so it's eager); google provides memoryEmbeddingProviders: ["gemini"] which the memory boot path needs; voice-call's manifest has activation.onStartup: true. openai and xai only declare contracts (realtime-voice, text-inference, etc.) and have onStartup: false, so they're not in the eager-load set.

Workaround

Patch the bundled openai plugin manifest to set activation.onStartup: true:

python3 - <<'PY'
import json
p = '/path/to/openclaw/dist/extensions/openai/openclaw.plugin.json'
d = json.load(open(p))
d['activation']['onStartup'] = True
json.dump(d, open(p, 'w'), indent=2)
PY

After this, gateway startup shows 4 plugins: google, memory-core, openai, voice-call and [voice-call] Realtime voice provider: openai — works.

This survives until the next openclaw update, after which it must be re-applied.

Root cause (proposed)

When the voice-call plugin's runtime initializes and realtime.enabled is true, resolveConfiguredRealtimeVoiceProvider calls into resolvePluginCapabilityProviders({ key: "realtimeVoiceProviders", cfg }) in dist/capability-provider-runtime-*.js. With getLoadedRuntimePluginRegistry() already populated (google has loaded), activeProviders is non-empty ([google]) but missingRequestedProviders is {"openai"} after the active filter. The fallback path then calls resolveCachedCapabilityProviderEntriesloadCapabilityProviderEntries, which does getLoadedRuntimePluginRegistry() again and short-circuits to loadedEntries (which is [google]) without attempting to cold-load openai from disk — because cold-loading (resolveRuntimePluginRegistry) only runs when the loaded registry is null:

const coldEntries = (loadedRegistry ? void 0 : resolveRuntimePluginRegistry(params.loadOptions))?.[params.key] ?? [];

So once any plugin is loaded, subsequent capability lookups for plugins that haven't been loaded yet won't dynamically pull them in.

Impact and severity

Affected: anyone using voice-call realtime with a provider plugin (openai, in practice) whose manifest doesn't have onStartup: true and isn't otherwise eagerly loaded. Severity: High (total loss of inbound realtime voice; misleading voicecall setup output). Frequency: 100% reproducible on a clean install.

Possible fixes

  1. Targeted: when voice-call.config.realtime.enabled is true, ensure the configured provider's plugin (realtimeVoiceProviders contract) is loaded before voice-call's runtime initializes. Could be done in the loader's pre-startup phase by walking voice-call's needed-contract set, or in voice-call's register() by declaring a dependency.
  2. General: in loadCapabilityProviderEntries, when loadedRegistry is non-null but is missing requested providers, also run the cold-load path for the missing ones (rather than short-circuiting).
  3. Stop-gap: add activation.onStartup: true to the bundled provider plugins that own realtimeVoiceProviders / realtimeTranscriptionProviders contracts (openai, google). Simple, but means openai always runs even when only used for realtime voice.

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…

FAQ

Expected behavior

Inbound call connects to OpenAI realtime voice and the agent responds.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix voice-call realtime: "Realtime voice provider \"openai\" is not registered" on startup — load-order bug similar to #60936 but on realtime voice path [1 pull requests, 1 comments, 2 participants]