## TL;DR
TAB_PARSING_FAILED means the tabs in your composite-template request point at something that does not exist in the assembled envelope: a recipient role with no matching recipient, a documentId the tabs reference but the documents array dropped, or conflicting sequence numbers across composite templates. List the template's real recipients and roles, match every tab to a live recipientId, and renumber your composite template sequence starting at 1. Tabs are validated against the assembled envelope, not the server template alone, so the fix is always in the request you send.

## The query
```text
DocuSign 'TAB_PARSING_FAILED' on composite templates  -  how to fix
```

## Use this when
- The create-envelope call returns errorCode TAB_PARSING_FAILED and you are using compositeTemplates
- Tabs were defined on a server template but the API request overrides recipients or documents
- You combine a server template, inline templates, and PDF bytes in one envelopeDefinition

## Not for
- Errors on plain (non-composite) template envelope creation - use the standard template-role check instead
- Signing ceremony errors that happen after the envelope is created successfully
- Recipient authentication failures - those surface as different error codes

## Steps
### 1. Read the full error, not just the code
Print the entire 400 response body. DocuSign nests the useful detail in `message`, which usually names the offending tab label, the recipient it expected, or the documentId it could not find. Log it verbatim before changing anything.
```python
print(resp.status_code)
print(resp.json()["message"])
```
Expected output: a message like `Tab parsing failed for tab [text1] on recipient [Signer 1]` that names the broken reference.

### 2. Verify composite-template sequence numbers are contiguous from 1
Each entry in `compositeTemplates` needs a `compositeTemplateId` (any unique string) and a `sequence` starting at "1" and incrementing with no gaps. A duplicated or skipped sequence makes DocuSign assemble the envelope in the wrong order, and tabs from a later template land on a document set that does not have their recipient yet.
```json
{
  "compositeTemplates": [
    {"compositeTemplateId": "1", "sequence": "1", "serverTemplates": [{"sequence": "1", "templateId": "[TEMPLATE_ID]"}]},
    {"compositeTemplateId": "2", "sequence": "2", "inlineTemplates": [{"sequence": "1", "recipients": {}}]}
  ]
}
```
Expected output: sequences 1, 2, 3 with no gaps; the error disappears if ordering was the cause.

### 3. Match every tab to a recipient that actually exists in the request
Open the server template in the DocuSign web console and write down the exact role names. Then check the `recipients` block of your inline template: each tab's `recipientId` (or `roleName`) must match a recipient defined in the assembled envelope. The classic trigger is overriding recipients in the API call while the template's tabs still point at the template's original role names.
```python
# fetch the template's real recipients first
r = requests.get(f"{base}/templates/{template_id}/recipients", headers=headers)
print([x["roleName"] for x in r.json().get("signers", [])])
```
Expected output: the role names printed from the API match the roleName values in your request byte for byte, including case and spaces.

### 4. Confirm the tabs point at documentIds that survived assembly
Tabs carry a `documentId`. If your request replaces the template's documents with fresh PDFs but keeps the template's documentIds, the tab references dangle. Either keep the template's documentIds when you supply replacement bytes, or re-map every tab to the new documentIds.
```json
"documents": [{"documentId": "1", "name": "contract.pdf", "documentBase64": "[BASE64_BYTES]"}]
```
Expected output: every tab's documentId appears in the documents array of the final request.

### 5. Rebuild the request minimally, then add pieces back
Send the simplest composite request that should work: one server template, one recipient, no overrides. When that succeeds, re-add the inline template overrides one at a time. The step where TAB_PARSING_FAILED returns identifies the conflicting block. Keep this minimal repro saved - it is the fastest way to validate template changes before they reach production.
Expected output: the minimal envelope creates with a 201, and you know exactly which override reintroduces the failure.

## Tool compatibility
DocuSign eSignature REST API v2.1 (composite templates are a v2.1 feature; the error and the fix are the same on the developer demo environment and production). Applies to any SDK that builds envelopeDefinition JSON (Python, Node, Java, C#). Not applicable to the SOAP API or to envelopes built purely in the web console.

## Variant phrasings
- DocuSign compositeTemplates returns TAB_PARSING_FAILED
- tabs failed to parse on composite template envelope creation
- DocuSign error TAB_PARSING_FAILED envelopeDefinition
- composite template tabs could not be parsed for recipient

## Why it happens
Composite templates are merged server-side: server templates, inline templates, and document bytes are layered by sequence number into one envelope. Tab parsing runs against that merged result. Any reference the merge cannot resolve - a role renamed in the UI but not in your code, a document replaced without its id, a sequence gap that reorders the layers - fails the whole parse instead of dropping the single tab, because a misplaced signature tab is a legal-integrity problem, not a cosmetic one.

## Edge cases / pitfalls
- Role names are case-sensitive and space-sensitive: "Signer 1" and "Signer1" are different roles.
- Document visibility rules can hide documents from recipients, which surfaces as tab parse failures on the hidden docs.
- Prefilled tabs (sender-owned) still need a valid recipient anchor - they cannot float without one.
- If the template was edited in the UI after you coded against it, re-pull the recipient list; UI edits rename roles silently.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_espWOdFHMy5jfyDVODyM5w
