← All breaking-change reports

Twilio dropped subresource_uris from SIP mappings: 6 fixable removals next to 6 that no codemod can touch

twilio · guide · 2026-08-04 · source: OpenAPI spec diff

What changed

Between twilio-oai 1.10.0 and 1.20.0, the Twilio 2010-04-01 API spec lost 12 response properties. Every one of them is the same change kind, response-prop-removed, and every one is genuinely breaking. Yet half are mendable by machine and half are not, and the split does not follow the change kind at all. It follows what the removed data actually was.

Six removals hit the SIP domain mapping resources. The subresource_uris map is gone from all four read shapes and both create shapes:

  • GET /2010-04-01/Accounts/{AccountSid}/SIP/Domains/{DomainSid}/CredentialListMappings.json, field credential_list_mappings[].subresource_uris (change 4128)
  • GET .../CredentialListMappings/{Sid}.json, field subresource_uris (4129)
  • GET .../IpAccessControlListMappings.json, field ip_access_control_list_mappings[].subresource_uris (4130)
  • GET .../IpAccessControlListMappings/{Sid}.json, field subresource_uris (4131)
  • POST .../CredentialListMappings.json 201, field subresource_uris (4135)
  • POST .../IpAccessControlListMappings.json 201, field subresource_uris (4136)

The other six hit call feedback summaries. The issues[] array stopped being a list of typed objects and became a flat list of issue labels, taking three fields with it on each of two endpoints:

  • GET /2010-04-01/Accounts/{AccountSid}/Calls/FeedbackSummary/{Sid}.json: issues[].count, issues[].description, issues[].percentage_of_total_calls (4125, 4126, 4127)
  • POST /2010-04-01/Accounts/{AccountSid}/Calls/FeedbackSummary.json 201: the same three (4132, 4133, 4134)

The whole 1.10.0 to 1.20.0 corridor holds 25 records: 12 breaking, 13 additive. The adjudication on the breaking dozen splits exactly 6 code-fixable, 6 not-code-fixable.

Who is affected

The two groups fail differently, and that difference is the whole point.

SIP mapping readers lose a convenience, not information. Code that followed mapping.subresource_uris.credential_lists to reach the underlying credential list now reads undefined and concatenates it into a URL. The request goes out malformed rather than throwing at the read site, which is the worst kind of failure to trace back. But nothing was actually lost. The mapping resource still returns the child SID, and 2010-04-01 URLs are a deterministic function of account SID plus resource SID. The spec confirms the compensation directly: the same diff adds domain_sid to all six mapping shapes (changes 4139 through 4142, plus 4148 and 4149). Twilio removed a precomputed link and left every input needed to compute it.

FeedbackSummary readers lose the data itself. A line like summary.issues.sort((a, b) => b.count - a.count)[0] now sorts strings by an undefined property. No later version of the spec exposes per-issue aggregate counts on any endpoint. There is no successor field, no alternate resource, no query parameter that brings the numbers back.

That asymmetry is why change kind is a useless triage signal on its own. Both groups are response-prop-removed. Both are breaking. One is a mechanical URL construction. The other is a product decision about whether to build your own aggregation pipeline or drop the metric.

How to fix it

Scanning tells you which of the two you are actually in, with file and line, and without your code leaving the machine:

npx mendapi scan --repo .

For the six SIP removals the adjudicated strategy is replace-uri-read-with-local-construction, at high confidence, with the spec evidence recorded alongside the verdict: subresource_uris appears 23 times in the cached 1.10.0 spec and 21 times at 1.20.0, absent from the mapping schema, while the child resources stay addressable at their conventional paths in every later version. The shape of the edit:

// before
const listUrl = mapping.subresource_uris.credential_lists;
const list = await fetchJson(`https://api.twilio.com${listUrl}`);

// after
const list = await fetchJson(`https://api.twilio.com/2010-04-01/Accounts/${accountSid}/SIP/CredentialLists/${mapping.sid}.json`);

For the six FeedbackSummary removals the recorded strategy is none-data-discontinued, and mendapi says so in the report rather than drafting a patch that pretends otherwise. The only mechanical help available there is defensive: treat issues entries as strings and delete property access on them. Restoring the metric is your call, not a codemod's.

There is no rule pack for either group. These twelve verdicts come from the adjudication layer, which is why a reason string and spec evidence ship with each record instead of a pack name. With your own LLM key configured, and mendapi never proxies credentials, the adjudication becomes a reviewable draft patch:

npx mendapi llmfix --from-report .mendapi/impact.json

Dry run is the default posture throughout: you review a diff, your working tree stays untouched. The Twilio tracker page carries all 12 verdicts with their evidence, and the Twilio parity capstone documents how this corridor was measured against oasdiff across 20 consecutive spec pairs.

Related

Change data is recorded from upstream provider releases, changelogs and OpenAPI spec diffs; every article names its source.