twilio-13222Twiliomedium

Invalid Attribute

A TwiML verb contains an attribute that is not valid for that verb type.

What this error means

Error 13222 is thrown when Twilio encounters a TwiML verb with an attribute that either does not exist for that verb or has a value outside the allowed set. Every TwiML verb has a defined list of supported attributes. For example, <Say> accepts 'voice', 'language', and 'loop', but not 'action' or 'timeout'. Providing an unrecognized attribute does not simply get ignored — Twilio strictly validates TwiML and will refuse to execute the document, causing the affected call flow to fail. This is a common source of subtle bugs when developers assume TwiML verbs share attributes across types.

Root causes

high

Using an attribute from one TwiML verb on the wrong verb (e.g., adding 'action' to <Say> instead of <Gather>)

Common

medium

Providing an attribute value outside the allowed enumerated set (e.g., method='DELETE' instead of 'GET' or 'POST')

Common

medium

Using attributes from an older API version that have been renamed or removed

Occasional

medium

Typo in an attribute name (e.g., 'laguage' instead of 'language' on <Say>)

Occasional

high

Dynamically generated attribute names from configuration variables containing incorrect values

Rare

medium

Copying TwiML examples from unofficial or outdated third-party documentation

Occasional

How to fix it

  1. 1

    Identify the invalid attribute from Twilio Debugger

    Open the Twilio Console and navigate to Monitor > Debugger. Find the 13222 error event and inspect the error details. Twilio typically identifies the specific attribute name and the verb it was placed on, giving you a precise target to fix.

  2. 2

    Consult the TwiML verb attribute reference

    For each verb in your TwiML, verify the allowed attributes at https://www.twilio.com/docs/voice/twiml. Each verb page lists every supported attribute and its allowed values. Pay special attention to attributes like 'method', 'statusCallback', 'action', and 'timeout', which are only available on specific verbs.

  3. 3

    Audit your TwiML for cross-verb attribute confusion

    Scan your TwiML generation code for cases where attributes intended for one verb are being applied to another. Common mistakes include applying <Gather> attributes to <Dial>, or using <Record> attributes on <Say>. Each verb has an entirely separate attribute namespace.

  4. 4

    Replace raw XML string construction with the Twilio helper library

    Use the Twilio SDK to build TwiML objects, which will raise compile-time or runtime errors for invalid attributes before the request reaches Twilio.

    // Node.js — SDK enforces valid attributes at construction time
    const twilio = require('twilio');
    
    app.post('/webhook', (req, res) => {
      const twiml = new twilio.twiml.VoiceResponse();
      
      // <Gather> with valid attributes
      const gather = twiml.gather({
        action: '/handle-input',
        method: 'POST',
        timeout: 5,
        numDigits: 1
      });
      gather.say('Press 1 for sales, press 2 for support.');
      
      res.type('text/xml');
      res.send(twiml.toString());
    });
  5. 5

    Validate attribute values against allowed enumerations

    For attributes with limited allowed values, validate programmatically before generating TwiML. For example, the 'method' attribute on <Redirect>, <Gather>, and <Record> only accepts 'GET' or 'POST'. The 'voice' attribute on <Say> only accepts specific Amazon Polly or Twilio voice names.

  6. 6

    Write unit tests for all TwiML-generating webhook handlers

    Add tests that call each webhook endpoint and parse the returned TwiML using an XML parser. Assert that all elements and attributes match expected values. This catches attribute errors before deployment.

    // Jest test — validate TwiML attribute correctness
    const request = require('supertest');
    const { parseStringPromise } = require('xml2js');
    
    test('webhook returns valid TwiML with correct Gather attributes', async () => {
      const response = await request(app).post('/webhook');
      expect(response.status).toBe(200);
      
      const parsed = await parseStringPromise(response.text);
      const gather = parsed.Response.Gather[0];
      expect(gather.$.method).toMatch(/^(GET|POST)$/);
      expect(Number(gather.$.timeout)).toBeGreaterThan(0);
    });
  7. 7

    Review changelog for deprecated attributes

    If you're migrating from older Twilio API versions, check the Twilio changelog at https://www.twilio.com/en-us/changelog for attributes that have been deprecated, renamed, or removed. Attributes like 'sendDigits' have moved between verbs across versions.

Prevention

Prevent 13222 errors by using Twilio's official SDK libraries to construct all TwiML programmatically — the SDKs enforce attribute validity at the object level and will raise errors in your application before invalid XML ever reaches Twilio. Maintain a comprehensive test suite that validates TwiML output from every webhook handler. Reference the official TwiML documentation when adding new verbs or attributes, and avoid copying examples from unofficial sources. When upgrading the Twilio SDK, review the changelog for attribute changes and update your TwiML accordingly. Use integration tests in a staging environment with real Twilio phone numbers to catch TwiML validation errors before they affect production calls.

Debugging this right now?

Sherlock diagnoses twilio-13222 automatically. Just ask in Slack and get an instant root-cause analysis.

Add to Slack — Free