Skip to content

fix(voice-call): add missing fields to plugin config JSON Schema#38892

Closed
giumex wants to merge 1 commit into
openclaw:mainfrom
giumex:fix/voice-call-plugin-schema-missing-fields
Closed

fix(voice-call): add missing fields to plugin config JSON Schema#38892
giumex wants to merge 1 commit into
openclaw:mainfrom
giumex:fix/voice-call-plugin-schema-missing-fields

Conversation

@giumex

@giumex giumex commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

The plugin manifest configSchema (openclaw.plugin.json) was missing several fields that the Zod schema and runtime code support, causing the gateway to reject valid config with additionalProperties errors.

Add:

  • webhookSecurity object (allowedHosts, trustForwardingHeaders, trustedProxyIPs)
  • streaming sub-fields (preStartTimeoutMs, maxPendingConnections, maxPendingConnectionsPerIp, maxConnections)
  • staleCallReaperSeconds

Summary

  • Problem: The voice-call plugin manifest (openclaw.plugin.json) declares "additionalProperties": false but is missing several config fields that the Zod schema, runtime code, and official docs all support. The gateway's AJV validation rejects these fields before the plugin ever loads, making documented config like webhookSecurity and streaming security limits unusable.
  • Why it matters: Users following the docs (e.g. the Webhook Security and Streaming sections) get a gateway startup failure with no clear indication that the config is actually valid but the schema is incomplete.
  • What changed: Added the missing properties to configSchema in extensions/voice-call/openclaw.plugin.json so AJV accepts them, and the existing Zod validation + runtime code can use them as designed.
  • What did NOT change (scope boundary): No runtime logic, no Zod schemas, no docs, no tests modified. This is a pure JSON Schema alignment fix in the plugin manifest.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • 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

User-visible / Behavior Changes

Users can now set these config fields without the gateway rejecting them on startup:

Field Location in config What it controls
webhookSecurity.allowedHosts top-level Allowlisted hosts for forwarded header trust
webhookSecurity.trustForwardingHeaders top-level Trust forwarded headers without allowlist
webhookSecurity.trustedProxyIPs top-level Only trust forwarded headers from specific proxy IPs
streaming.preStartTimeoutMs streaming Close sockets that never send a valid start frame
streaming.maxPendingConnections streaming Cap total unauthenticated pre-start sockets
streaming.maxPendingConnectionsPerIp streaming Cap pre-start sockets per source IP
streaming.maxConnections streaming Hard cap for all open media stream sockets
staleCallReaperSeconds top-level Auto-reap calls stuck in non-terminal states

No defaults change. Users who don't set these fields are unaffected.

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

Note: This fix unblocks security-hardening config (webhookSecurity, streaming rate limits) that was already implemented in runtime code but unreachable due to the schema gap.

Repro + Verification

Environment

  • OS: macOS (also reproducible on Linux)
  • Runtime/container: Node 22+
  • Integration/channel: voice-call plugin (Twilio/Plivo/Telnyx)
  • Relevant config (redacted):
{
  plugins: {
    entries: {
      "voice-call": {
        enabled: true,
        config: {
          provider: "twilio",
          webhookSecurity: {
            allowedHosts: ["voice.example.com"],
          },
          streaming: {
            enabled: true,
            maxPendingConnections: 16,
          },
          staleCallReaperSeconds: 180,
        },
      },
    },
  },
}

Steps to reproduce (before fix)

  1. Add any of the missing fields (webhookSecurity, streaming.maxPendingConnections, staleCallReaperSeconds, etc.) to voice-call plugin config
  2. Start the gateway (openclaw gateway run)
  3. Observe gateway fails to start with config validation error

Expected

  • Gateway starts and the plugin loads with the documented config

Actual (before fix)

  • Gateway rejects config: AJV reports additionalProperties violation for the undeclared fields

After fix

  • Tested on a live OpenClaw installation with the patched openclaw.plugin.json. Gateway starts successfully and the plugin loads with all documented fields accepted.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets

Root cause trace:

  1. src/plugins/loader.ts:778-787 calls validatePluginConfig with the manifest's configSchema
  2. src/plugins/schema-validator.ts:21-25 initializes AJV with removeAdditional: false
  3. The manifest's top-level "additionalProperties": false (line 164) rejects webhookSecurity and staleCallReaperSeconds
  4. The manifest's streaming sub-object "additionalProperties": false (line 318) rejects preStartTimeoutMs, maxPendingConnections, maxPendingConnectionsPerIp, maxConnections
  5. The plugin is skipped entirely (continue at line 787)

Meanwhile, the Zod schema (extensions/voice-call/src/config.ts:253-350) and all runtime consumers (runtime.ts:112,125, webhook.ts:87-90, media-stream.ts:97-101) fully support these fields.

Human Verification (required)

  • Verified scenarios: Tested on a live OpenClaw installation -- gateway starts successfully with webhookSecurity, streaming security limits, and staleCallReaperSeconds all present in config. Before the fix, the same config caused a gateway startup failure. Also ran extensions/voice-call/src/config.test.ts (7 tests), src/config/config.plugin-validation.test.ts (8 tests), src/plugins/voice-call.plugin.test.ts (7 tests), src/plugins/schema-validator.test.ts (7 tests) -- all pass.
  • Edge cases checked: Verified JSON is valid after edit. Confirmed no other fields are missing by diffing every property in VoiceCallConfigSchema (Zod) against the configSchema (JSON Schema).
  • What I did not verify: End-to-end voice call with these specific fields actively exercised (e.g. an actual proxied webhook hitting allowedHosts), but the runtime code paths are already covered by existing unit tests.

Compatibility / Migration

  • Backward compatible? Yes -- only adds new accepted properties; existing configs are unaffected
  • Config/env changes? No
  • Migration needed? No

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: Revert the single commit (one file changed)
  • Files/config to restore: extensions/voice-call/openclaw.plugin.json
  • Known bad symptoms reviewers should watch for: If a typo were introduced in the JSON, the manifest would fail to parse and the plugin wouldn't load at all -- but CI JSON validation and the existing plugin tests catch this.

Risks and Mitigations

  • Risk: A typo in the JSON Schema could silently accept invalid config values.
    • Mitigation: The new schema entries mirror the exact types and constraints from the Zod schema. The Zod layer (config.ts) remains the authoritative runtime validator and will still reject truly invalid values (wrong types, out-of-range numbers, etc.) even if AJV passes them through.

The plugin manifest configSchema (openclaw.plugin.json) was missing
several fields that the Zod schema and runtime code support, causing
the gateway to reject valid config with additionalProperties errors.

Add:
- webhookSecurity object (allowedHosts, trustForwardingHeaders, trustedProxyIPs)
- streaming sub-fields (preStartTimeoutMs, maxPendingConnections,
  maxPendingConnectionsPerIp, maxConnections)
- staleCallReaperSeconds
@openclaw-barnacle openclaw-barnacle Bot added channel: voice-call Channel integration: voice-call size: XS labels Mar 7, 2026
@greptile-apps

greptile-apps Bot commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a schema alignment bug in the voice-call plugin manifest (openclaw.plugin.json) where "additionalProperties": false was set but several fields supported by the Zod schema and runtime code were absent, causing AJV to reject valid user configurations on gateway startup.

Key changes:

  • staleCallReaperSeconds added at the top level — matches Zod's z.number().int().nonnegative() with minimum: 0
  • webhookSecurity object added with allowedHosts, trustForwardingHeaders, and trustedProxyIPs — types match the Zod schema ✓
  • streaming sub-fields preStartTimeoutMs, maxPendingConnections, maxPendingConnectionsPerIp, and maxConnections added — all use minimum: 1 matching Zod's .positive() constraint ✓
  • Minor: allowedHosts and trustedProxyIPs items don't include minLength: 1 to match Zod's z.string().min(1), though this is non-critical since Zod remains the authoritative runtime validator.

Confidence Score: 5/5

  • Safe to merge — purely additive JSON Schema change that unblocks documented, already-implemented config fields.
  • The change is a minimal, additive fix to a single JSON file. All new schema entries were cross-checked against the authoritative Zod schema and match types and constraints correctly. No runtime logic, tests, or defaults are altered. The only finding is a minor style gap (missing minLength: 1 on string array items) that is non-critical since Zod enforces it at runtime.
  • No files require special attention.

Last reviewed commit: aa531db

Comment thread extensions/voice-call/openclaw.plugin.json
@steipete

steipete commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

Landed on main via cf290e31bd4f99dd58714ade6e36a38b6f9089ec.

What was landed:

  • added the missing voice-call manifest schema fields (webhookSecurity, staleCallReaperSeconds, and streaming guard fields)
  • added regression coverage in src/config/config.plugin-validation.test.ts that loads the voice-call manifest schema and verifies these config fields are accepted
  • added a changelog entry under 2026.3.7

Validation before commit:

  • targeted: pnpm vitest run src/config/config.plugin-validation.test.ts src/plugins/voice-call.plugin.test.ts extensions/voice-call/src/config.test.ts src/plugins/schema-validator.test.ts
  • full gate: pnpm lint && pnpm build && pnpm test

Thanks for the fix and clear write-up, @giumex.

@steipete

steipete commented Mar 7, 2026

Copy link
Copy Markdown
Contributor

Closed as landed in cf290e31bd4f99dd58714ade6e36a38b6f9089ec. Thanks again!

@steipete steipete closed this Mar 7, 2026
vincentkoc pushed a commit to BryanTegomoh/openclaw-contrib that referenced this pull request Mar 8, 2026
openperf pushed a commit to openperf/moltbot that referenced this pull request Mar 8, 2026
mcaxtr pushed a commit to mcaxtr/openclaw that referenced this pull request Mar 8, 2026
GordonSH-oss pushed a commit to GordonSH-oss/openclaw that referenced this pull request Mar 9, 2026
jenawant pushed a commit to jenawant/openclaw that referenced this pull request Mar 10, 2026
V-Gutierrez pushed a commit to V-Gutierrez/openclaw-vendor that referenced this pull request Mar 17, 2026
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 21, 2026
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 21, 2026
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 21, 2026
lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: voice-call Channel integration: voice-call size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants