ConversationRelayAttributes defines speechtimeout (lowercase) but TwiML spec requires speechTimeout (camelCase)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 1.5k
- Forks
- 564
- Avg merge
- 14h 2m
- Merged PRs (30d)
- 3
Description
Describe the bug
The ConversationRelayAttributes interface in VoiceResponse.d.ts defines the attribute as speechtimeout (all lowercase). When developers follow the TypeScript types and pass speechtimeout, the SDK serializes it as speechtimeout="..." in the generated TwiML.
However, the TwiML spec for <ConversationRelay> documents this attribute as speechTimeout (camelCase). Twilio's TwiML validator is case-sensitive for attribute names, so the lowercase attribute is treated as unknown. Calls fail with a TwiML validation error (e.g. "Misspelled or unknown attributes") and ConversationRelay does not start.
At runtime, passing speechTimeout (camelCase) produces correct XML, but TypeScript reports an error because only speechtimeout is declared on ConversationRelayAttributes:
Object literal may only specify known properties, but 'speechTimeout' does not exist in type 'ConversationRelayAttributes'. Did you mean to write 'speechtimeout'?
This mismatch between the TypeScript definition, XML output, and the TwiML spec forces consumers to either ignore the type checker or post-process the XML string.
Note: CHANGES.md lists the attribute as speechTimeout when it was added to <ConversationRelay>, which suggests the intended name is camelCase.
Code snippet
const { twiml } = require('twilio');
// Following the TypeScript definition (speechtimeout)
const response1 = new twiml.VoiceResponse();
response1.connect().conversationRelay({
url: 'wss://example.test/ws',
speechtimeout: '2000',
});
console.log(response1.toString());
// Using camelCase (works at runtime, rejected by TypeScript)
const response2 = new twiml.VoiceResponse();
response2.connect().conversationRelay({
url: 'wss://example.test/ws',
speechTimeout: '2000',
});
console.log(response2.toString());
Actual behavior
With speechtimeout (as defined in ConversationRelayAttributes):
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Connect>
<ConversationRelay url="wss://example.test/ws" speechtimeout="2000"/>
</Connect>
</Response>
Twilio rejects this TwiML with a validation error (unknown attribute).
With speechTimeout at runtime (not in the type definition):
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Connect>
<ConversationRelay url="wss://example.test/ws" speechTimeout="2000"/>
</Connect>
</Response>
This output matches the TwiML spec and is accepted by Twilio.
Expected behavior
ConversationRelayAttributesshould declarespeechTimeout(camelCase), notspeechtimeout.- Passing
speechTimeout: '2000'should be the typed, documented way to set the attribute. - Generated TwiML should always emit
speechTimeout, per the TwiML spec.
twilio-node version
6.0.2
Node.js version
22.x
Logs or error messages
Twilio Debugger / Voice error when using speechtimeout in generated TwiML:
Possible Causes: Misspelled verbs; Incorrect case for verbs; Misspelled or unknown attributes; Unknown or unexpected nested elements.
Additional context
Current workaround: pass speechtimeout and post-process the XML:
response.toString().replace('speechtimeout=', 'speechTimeout=');
Or omit the attribute and rely on the default (auto).
A similar spec-vs-SDK mismatch for ConversationRelay attributes was reported for the C# helper library in twilio-csharp#829.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in VoiceResponse.d.ts at the ConversationRelayAttributes interface and compare its attribute spelling with the ConversationRelay TwiML specification and the speechTimeout entry in CHANGES.md. Make the TypeScript declaration match the camelCase runtime output, then verify that speechTimeout is accepted by the type checker and emitted in generated TwiML.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, typescript
- Domain
- api
- Issue type
- Bug
- Difficulty
- 1/5
- Estimated time
- Under an hour
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100