{
  "schemaVersion": "1.0",
  "title": "Troubleshoot the Twenty connector",
  "description": "Use this runbook to identify the first safe check for a Twenty connector failure. Preserve original instance, replica, Action, key, provider, replay, event, and outbox identities before changing configuration or state.",
  "canonical": "https://getaip.org/docs/connectors/twenty/troubleshooting",
  "route": "/docs/connectors/twenty/troubleshooting",
  "source": "docs/connectors/twenty/troubleshooting/README.md",
  "protocol": "Agent Interoperability Protocol",
  "protocolVersion": "1.0",
  "section": "Connectors",
  "documentType": "Connector",
  "language": "en",
  "downloads": {
    "md": "/docs/download/connectors/twenty/troubleshooting.md",
    "txt": "/docs/download/connectors/twenty/troubleshooting.txt",
    "json": "/docs/download/connectors/twenty/troubleshooting.json",
    "pdf": "/docs/download/connectors/twenty/troubleshooting.pdf"
  },
  "content": {
    "format": "text/markdown",
    "markdown": "---\ntitle: Troubleshoot the Twenty connector\ndescription: >-\n  Map startup, routing, Action, provider, mutation, metadata, webhook, and\n  storage symptoms to safe checks and recovery decisions\nkind: runbook\naudience: operator\nappliesTo: \"1.x\"\nwritingStandard: \"aip-docs/1.0\"\nlastReviewedRevision: \"97be86e9efedf07ecf1783b03800f683f107fb04\"\nconnector: twenty\naliases:\n  - Twenty connector troubleshooting\n  - Twenty connector errors\n---\n\n# Troubleshoot the Twenty connector\n\nUse this runbook to identify the first safe check for a Twenty connector\nfailure. Preserve original instance, replica, Action, key, provider, replay,\nevent, and outbox identities before changing configuration or state.\n\nBegin with the narrowest symptom. Escalate with bounded evidence when the\nlisted check cannot establish a safe recovery.\n\n## Triage before changing state\n\nCapture:\n\n- `/health`, `/ready`, and `/metrics` from the affected replica;\n- connector type, version, instance, replica, artifact, and configuration revision;\n- tenant, external account, workspace, and credential revision;\n- operation allowlist digest and discovered manifest digest;\n- Action ID, capability, canonical input hash, approval, and key digest;\n- provider HTTP status, request ID, error code, retryable, and uncertain flags;\n- webhook response, bounded header validation, event ID, replay scope, and outbox state;\n- PostgreSQL, registry lease, lifecycle, and deployment events.\n\nDo not capture provider token, webhook secret, signing seed, database password,\nfull idempotency key, raw webhook body, or unredacted personal data.\n\nRemove a not-ready replica from new assignments. Do not delete its database or\nstart a duplicate replica identity during triage.\n\n## Diagnose startup failures\n\n| Symptom | First check | Do not |\n|---|---|---|\n| Base URL rejected | Require a host, allowed scheme, and no credentials, path, query, or fragment | Enable broad HTTP or redirects |\n| Workspace rejected | Supply a canonical RFC 4122 UUID version 1 through 5 | Replace it with an AIP tenant string |\n| API token file rejected | Check regular-file type, owner-only mode, UTF-8, non-empty content, and 16 KiB bound | Print or move the token into environment text |\n| Webhook secret file rejected | Apply the same secret-file checks to a distinct secret | Reuse the provider API token |\n| Response bound rejected | Choose `1` through `268435456` bytes | Raise unrelated ingress limits |\n| Operation file rejected | Check 128 KiB, JSON string array, known suffixes, and non-empty set | Add arbitrary paths as suffixes |\n| Webhook secret causes startup failure | Configure an authorized central event endpoint and trust path | Mount the route without durable publication |\n| External-account fields rejected | Configure ID and system together or omit both | Assume the host compares them with workspace automatically |\n| Credential handle rejected | Configure ID, issuer, non-empty scopes, and revision as one unit | Drop revision fencing to pass startup |\n| DID or signing seed rejected | Verify exact file/value exclusivity and key encoding | Generate replacement identity without admission review |\n\nStartup validation is fail-closed. Correct the deployment record or secret\nprojection and replace the replica through the lifecycle process.\n\n## Diagnose liveness and readiness\n\n| Observation | Meaning | Next check |\n|---|---|---|\n| `/health` fails | Process, listener, ingress, or container boundary | Process exit and bind ownership |\n| `/health` passes, `/ready` returns `503` | At least one route-eligibility condition failed | Structured readiness fields |\n| `draining: true` | Lifecycle intentionally removed readiness | Drain owner and in-flight count |\n| `lease_valid: false` | Registry lease expired or recovery has not committed | Control-plane identity and lease metrics |\n| `runtime.ready: false` | Durable runtime store probe failed | PostgreSQL and recovery report |\n| `connector.ready: false` | Authenticated core OpenAPI probe failed | Origin, TLS, token, workspace, provider status |\n\nThe connector health probe exercises only `GET /rest/open-api/core`. A passing\nprobe does not prove mutation, metadata, webhook, or custom-object permission.\n\nDo not force route weight onto a `503` replica. Restore all readiness conditions\nand observe the exact lease before reassignment.\n\n## Diagnose missing or rejected capabilities\n\n| Symptom | First check | Decision |\n|---|---|---|\n| Capability absent from discovery | Compare operation file, manifest, admission, tenant, route, and lifecycle | Admit the intended fixed suffix through change control |\n| Capability present but invocation says operation not allowed | Compare running process allowlist with admitted manifest | Remove route and correct configuration drift |\n| Another tenant cannot discover the capability | Verify tenant and external-account route binding | Treat as expected isolation unless policy says otherwise |\n| A syntactically valid new suffix is rejected | Compare with the 22-operation source catalogue | Add a typed source operation; do not tunnel a path |\n| Manifest count differs | Compare allowlist set, artifact digest, and config revision | Re-admit the exact replacement artifact and manifest |\n\nDiscovery is an authorization and routing projection. Editing an operation file\ndoes not update a running host.\n\n## Diagnose invalid input\n\n`connector.twenty.invalid_request` is a permanent precondition failure for\nthese common causes:\n\n| Message or context | Correction |\n|---|---|\n| Object grammar | Use 1 through 128 ASCII alphanumeric or underscore characters, starting with a letter |\n| Record or metadata UUID | Use an RFC 4122 UUID version 1 through 5 |\n| Unknown metadata resource | Choose one of the twelve fixed resource names |\n| Missing or non-object body | Supply the operation's required JSON body shape |\n| Create-many count | Supply 1 through 200 object bodies |\n| Duplicate body alternatives | Supply exactly one of `data` or `ids`, with 1 through 200 members |\n| Merge IDs | Supply 2 through 9 unique UUIDs |\n| Merge priority | Use an index smaller than the actual ID array length |\n| Unknown or null query | Use only the operation's closed query set and non-null values |\n| Bulk mutation filter | Supply a non-empty value other than whitespace, `{}`, or `null` |\n| Missing mutation key | Supply 1 through 1,024 ASCII graphic bytes |\n| Request body too large | Keep serialized provider JSON within 16 MiB |\n\nCorrected input is a new intent when semantics change. Do not reuse an\nidempotency key that already owns a different canonical input hash.\n\n## Diagnose provider failures\n\n| Connector code | Category | First decision |\n|---|---|---|\n| `connector.twenty.authentication` | Auth | Verify fixed token, origin, workspace, credential revision, and provider permission |\n| `connector.twenty.remote_temporary` | Temporary | Preserve Action and apply its operation-specific retry contract |\n| `connector.twenty.remote_rejected` | Permanent | Compare current provider schema, body, filter, ID, and permission |\n| `connector.twenty.transport` | Temporary | Determine connect failure versus post-connection ambiguity |\n| `connector.twenty.invalid_response` | Connector | Check response limit, JSON validity, proxy transformation, and provider drift |\n| `connector.twenty.storage` | Temporary | Restore replay profile state without replacing scope |\n\nProvider `401` and `403` map to authentication and are not retryable or\nuncertain. Provider `429` and `5xx` map to temporary failure.\n\nOther provider non-success statuses map to permanent rejection. Retained error\ndetails contain only bounded safe fields, so use provider-side evidence under\nappropriate access when more context is required.\n\n## Decide whether a retry is safe\n\n| Operation class | Connector retry support | Required decision |\n|---|---:|---|\n| Eight reads | Yes | Repeat the same read intent according to policy |\n| `record.create` | Yes | Original Action, key, workspace, object, body, and array index only |\n| `record.create_many` | Yes | Original Action, key, unchanged array order and bodies only |\n| `record.update` | Yes | Original Action, key, target, and body only |\n| Other eleven mutations | No | Reconcile provider state before another write |\n\n`retryable: true` does not authorize a new Action, new key, changed input, or\ndifferent external account. `uncertain_outcome: true` means another provider\neffect can be unsafe even when retryable is false.\n\nThe connector exposes no reconciliation capability. Use bounded authorized\nreads, provider audit evidence, and the original AIP chain.\n\n## Diagnose deterministic create behavior\n\n| Symptom | First check |\n|---|---|\n| Create returns an existing record | Verify forced `upsert=true`, workspace, key, and derived or explicit ID |\n| Batch member targets an unexpected ID | Compare original array order and zero-based index |\n| Explicit ID is rejected | Validate RFC 4122 version and variant |\n| Repeated create collides | Compare canonical input hash and key ownership |\n| Provider result lacks a usable ID | Stop and perform a bounded read; do not guess or repeat create |\n\nThe connector derives missing UUID v5 values from workspace, key, and index.\nChanging any input changes deterministic ownership.\n\nUpsert and deterministic IDs limit duplicate risk. They do not prove global\nexactly-once provider behavior.\n\n## Diagnose metadata and webhook-secret input\n\n| Symptom | First check |\n|---|---|\n| Metadata resource rejected | Use one of the twelve fixed names and an operation allowed for it |\n| Page-layout type ignored or rejected | Supply valid type with `objectMetadataId` |\n| Tabs or widgets list rejected | Supply required `pageLayoutId` or `pageLayoutTabId` UUID |\n| Webhook create rejects `secret` | Remove it; connector injects the host-owned value |\n| Webhook create rejects rotation control | Remove `rotateConfiguredSecret`; it is update-only |\n| Webhook update rejects rotation | Use exactly Boolean `true`, not `false` or a string |\n| Webhook mutation says not configured | Provision the host webhook secret and event endpoint through deployment |\n| Read-back omits a secret | Treat as expected recursive redaction |\n\nAll metadata mutations are critical and unsafe to retry. Refresh the provider\nmetadata schema and dependency graph before any replacement intent.\n\n## Diagnose restore and merge\n\n| Symptom | First check |\n|---|---|\n| Single restore uses a collection request | Expected mapping at pinned revision; connector adds `filter=id[eq]:<id>` |\n| Restore finds no record | Verify prior soft-delete state, exact workspace, object, and ID |\n| Restore after permanent destroy fails | Expected boundary; no connector rollback exists |\n| Merge body rejected | Check exact keys, 2-to-9 unique IDs, in-range priority, and Boolean dry-run |\n| Merge result is uncertain | Preserve all IDs and read current survivor state before another mutation |\n\nThe single-restore workaround exists because the pinned provider path parser\nrejects its declared three-segment route. Requalify this mapping when provider\nrevision changes.\n\n## Diagnose webhook HTTP responses\n\n| Response | First checks | Unsafe workaround |\n|---|---|---|\n| `400 webhook.missing_header` | Exact three header names, encoding, and non-empty values | Synthesizing headers at an untrusted proxy |\n| `401 webhook.authentication_failed` | Raw bytes, time, signature, secret revision, nonce, JSON, workspace, payload fields | Logging secret or body to reveal subreason |\n| `503 webhook.storage_unavailable` | Replay store, event log, PostgreSQL, profile state, durable outbox | Clearing replay or outbox state |\n| `200 centrally_acknowledged` | Search central event by deterministic ID | Treating it as proof of downstream consumer completion |\n| `200 durably_queued` | Inspect local outbox and central route | Asking provider to resend the same nonce |\n\nNonce admission happens before JSON validation and event persistence. A late\nfailure can leave the nonce fenced without a published event.\n\nRecover from the stage that owns the delivery. Do not change instance identity,\nevent ID, or nonce merely to bypass the fence.\n\n## Diagnose storage, lease, and drain state\n\n| Symptom | First check | Recovery boundary |\n|---|---|---|\n| Runtime storage not ready | Database URL, TLS, role, capacity, locks, and recovery report | Preserve Action, replay, event, and outbox state |\n| Admission blocked by recovery errors | Exact queued-Action and delegation records | Repair records; do not force registration |\n| Lease expired | Provider and storage readiness plus control-plane path | Stable recovery request identity |\n| Repeated heartbeat failure | Connector probe, storage probe, TLS, DID, registry identity | Keep replica unrouted |\n| Drain does not complete | In-flight gauge and original Action statuses | Wait within deadline, then preserve uncertainty |\n| Offline transition fails | Control-plane state and old lease identity | Do not start duplicate replica ID |\n\nAn empty replacement database is not recovery. It can remove durable fences\nwhile provider effects and central events remain.\n\n## Prepare an escalation bundle\n\nInclude:\n\n- exact source revision and immutable host image digest;\n- connector version, instance, replica, tenant, workspace, and config revision;\n- redacted effective configuration and operation allowlist digest;\n- `/ready` body and bounded metric snapshot;\n- Action, approval, key digest, checkpoint, result, error, and receipt identities;\n- provider status and bounded request ID;\n- for webhooks, response class, header-shape results, replay scope, event ID, and outbox outcome;\n- PostgreSQL recovery, lease, drain, deployment, and incident timestamps;\n- commands and decisions already applied;\n- explicit missing evidence and unresolved uncertainty.\n\nExclude secret bytes and unredacted customer data. State whether evidence comes\nfrom source review, deployed artifact inspection, controlled execution, or live\nprovider observation.\n\n## Related documentation\n\n- [Twenty connector configuration](../reference/configuration.md)\n- [Twenty capability index](../capabilities/README.md)\n- [Twenty health, observability, and recovery](../operations/health-observability-and-recovery.md)\n- [Twenty webhook security, replay, and events](../reference/webhook-security-replay-and-events.md)\n- [Errors and retry decisions](../../../reference/errors.md)\n",
    "text": "Troubleshoot the Twenty connector\n\nUse this runbook to identify the first safe check for a Twenty connector\nfailure. Preserve original instance, replica, Action, key, provider, replay,\nevent, and outbox identities before changing configuration or state.\n\nBegin with the narrowest symptom. Escalate with bounded evidence when the\nlisted check cannot establish a safe recovery.\n\nTriage before changing state\n\nCapture:\n• /health, /ready, and /metrics from the affected replica;\n• connector type, version, instance, replica, artifact, and configuration revision;\n• tenant, external account, workspace, and credential revision;\n• operation allowlist digest and discovered manifest digest;\n• Action ID, capability, canonical input hash, approval, and key digest;\n• provider HTTP status, request ID, error code, retryable, and uncertain flags;\n• webhook response, bounded header validation, event ID, replay scope, and outbox state;\n• PostgreSQL, registry lease, lifecycle, and deployment events.\n\nDo not capture provider token, webhook secret, signing seed, database password,\nfull idempotency key, raw webhook body, or unredacted personal data.\n\nRemove a not-ready replica from new assignments. Do not delete its database or\nstart a duplicate replica identity during triage.\n\nDiagnose startup failures\n\n| Symptom | First check | Do not |\n\n| Base URL rejected | Require a host, allowed scheme, and no credentials, path, query, or fragment | Enable broad HTTP or redirects |\n| Workspace rejected | Supply a canonical RFC 4122 UUID version 1 through 5 | Replace it with an AIP tenant string |\n| API token file rejected | Check regular-file type, owner-only mode, UTF-8, non-empty content, and 16 KiB bound | Print or move the token into environment text |\n| Webhook secret file rejected | Apply the same secret-file checks to a distinct secret | Reuse the provider API token |\n| Response bound rejected | Choose 1 through 268435456 bytes | Raise unrelated ingress limits |\n| Operation file rejected | Check 128 KiB, JSON string array, known suffixes, and non-empty set | Add arbitrary paths as suffixes |\n| Webhook secret causes startup failure | Configure an authorized central event endpoint and trust path | Mount the route without durable publication |\n| External-account fields rejected | Configure ID and system together or omit both | Assume the host compares them with workspace automatically |\n| Credential handle rejected | Configure ID, issuer, non-empty scopes, and revision as one unit | Drop revision fencing to pass startup |\n| DID or signing seed rejected | Verify exact file/value exclusivity and key encoding | Generate replacement identity without admission review |\n\nStartup validation is fail-closed. Correct the deployment record or secret\nprojection and replace the replica through the lifecycle process.\n\nDiagnose liveness and readiness\n\n| Observation | Meaning | Next check |\n\n| /health fails | Process, listener, ingress, or container boundary | Process exit and bind ownership |\n| /health passes, /ready returns 503 | At least one route-eligibility condition failed | Structured readiness fields |\n| draining: true | Lifecycle intentionally removed readiness | Drain owner and in-flight count |\n| leasevalid: false | Registry lease expired or recovery has not committed | Control-plane identity and lease metrics |\n| runtime.ready: false | Durable runtime store probe failed | PostgreSQL and recovery report |\n| connector.ready: false | Authenticated core OpenAPI probe failed | Origin, TLS, token, workspace, provider status |\n\nThe connector health probe exercises only GET /rest/open-api/core. A passing\nprobe does not prove mutation, metadata, webhook, or custom-object permission.\n\nDo not force route weight onto a 503 replica. Restore all readiness conditions\nand observe the exact lease before reassignment.\n\nDiagnose missing or rejected capabilities\n\n| Symptom | First check | Decision |\n\n| Capability absent from discovery | Compare operation file, manifest, admission, tenant, route, and lifecycle | Admit the intended fixed suffix through change control |\n| Capability present but invocation says operation not allowed | Compare running process allowlist with admitted manifest | Remove route and correct configuration drift |\n| Another tenant cannot discover the capability | Verify tenant and external-account route binding | Treat as expected isolation unless policy says otherwise |\n| A syntactically valid new suffix is rejected | Compare with the 22-operation source catalogue | Add a typed source operation; do not tunnel a path |\n| Manifest count differs | Compare allowlist set, artifact digest, and config revision | Re-admit the exact replacement artifact and manifest |\n\nDiscovery is an authorization and routing projection. Editing an operation file\ndoes not update a running host.\n\nDiagnose invalid input\n\nconnector.twenty.invalidrequest is a permanent precondition failure for\nthese common causes:\n\n| Message or context | Correction |\n\n| Object grammar | Use 1 through 128 ASCII alphanumeric or underscore characters, starting with a letter |\n| Record or metadata UUID | Use an RFC 4122 UUID version 1 through 5 |\n| Unknown metadata resource | Choose one of the twelve fixed resource names |\n| Missing or non-object body | Supply the operation's required JSON body shape |\n| Create-many count | Supply 1 through 200 object bodies |\n| Duplicate body alternatives | Supply exactly one of data or ids, with 1 through 200 members |\n| Merge IDs | Supply 2 through 9 unique UUIDs |\n| Merge priority | Use an index smaller than the actual ID array length |\n| Unknown or null query | Use only the operation's closed query set and non-null values |\n| Bulk mutation filter | Supply a non-empty value other than whitespace, {}, or null |\n| Missing mutation key | Supply 1 through 1,024 ASCII graphic bytes |\n| Request body too large | Keep serialized provider JSON within 16 MiB |\n\nCorrected input is a new intent when semantics change. Do not reuse an\nidempotency key that already owns a different canonical input hash.\n\nDiagnose provider failures\n\n| Connector code | Category | First decision |\n\n| connector.twenty.authentication | Auth | Verify fixed token, origin, workspace, credential revision, and provider permission |\n| connector.twenty.remotetemporary | Temporary | Preserve Action and apply its operation-specific retry contract |\n| connector.twenty.remoterejected | Permanent | Compare current provider schema, body, filter, ID, and permission |\n| connector.twenty.transport | Temporary | Determine connect failure versus post-connection ambiguity |\n| connector.twenty.invalidresponse | Connector | Check response limit, JSON validity, proxy transformation, and provider drift |\n| connector.twenty.storage | Temporary | Restore replay profile state without replacing scope |\n\nProvider 401 and 403 map to authentication and are not retryable or\nuncertain. Provider 429 and 5xx map to temporary failure.\n\nOther provider non-success statuses map to permanent rejection. Retained error\ndetails contain only bounded safe fields, so use provider-side evidence under\nappropriate access when more context is required.\n\nDecide whether a retry is safe\n\n| Operation class | Connector retry support | Required decision |\n\n| Eight reads | Yes | Repeat the same read intent according to policy |\n| record.create | Yes | Original Action, key, workspace, object, body, and array index only |\n| record.createmany | Yes | Original Action, key, unchanged array order and bodies only |\n| record.update | Yes | Original Action, key, target, and body only |\n| Other eleven mutations | No | Reconcile provider state before another write |\n\nretryable: true does not authorize a new Action, new key, changed input, or\ndifferent external account. uncertainoutcome: true means another provider\neffect can be unsafe even when retryable is false.\n\nThe connector exposes no reconciliation capability. Use bounded authorized\nreads, provider audit evidence, and the original AIP chain.\n\nDiagnose deterministic create behavior\n\n| Symptom | First check |\n\n| Create returns an existing record | Verify forced upsert=true, workspace, key, and derived or explicit ID |\n| Batch member targets an unexpected ID | Compare original array order and zero-based index |\n| Explicit ID is rejected | Validate RFC 4122 version and variant |\n| Repeated create collides | Compare canonical input hash and key ownership |\n| Provider result lacks a usable ID | Stop and perform a bounded read; do not guess or repeat create |\n\nThe connector derives missing UUID v5 values from workspace, key, and index.\nChanging any input changes deterministic ownership.\n\nUpsert and deterministic IDs limit duplicate risk. They do not prove global\nexactly-once provider behavior.\n\nDiagnose metadata and webhook-secret input\n\n| Symptom | First check |\n\n| Metadata resource rejected | Use one of the twelve fixed names and an operation allowed for it |\n| Page-layout type ignored or rejected | Supply valid type with objectMetadataId |\n| Tabs or widgets list rejected | Supply required pageLayoutId or pageLayoutTabId UUID |\n| Webhook create rejects secret | Remove it; connector injects the host-owned value |\n| Webhook create rejects rotation control | Remove rotateConfiguredSecret; it is update-only |\n| Webhook update rejects rotation | Use exactly Boolean true, not false or a string |\n| Webhook mutation says not configured | Provision the host webhook secret and event endpoint through deployment |\n| Read-back omits a secret | Treat as expected recursive redaction |\n\nAll metadata mutations are critical and unsafe to retry. Refresh the provider\nmetadata schema and dependency graph before any replacement intent.\n\nDiagnose restore and merge\n\n| Symptom | First check |\n\n| Single restore uses a collection request | Expected mapping at pinned revision; connector adds filter=id[eq]: |\n| Restore finds no record | Verify prior soft-delete state, exact workspace, object, and ID |\n| Restore after permanent destroy fails | Expected boundary; no connector rollback exists |\n| Merge body rejected | Check exact keys, 2-to-9 unique IDs, in-range priority, and Boolean dry-run |\n| Merge result is uncertain | Preserve all IDs and read current survivor state before another mutation |\n\nThe single-restore workaround exists because the pinned provider path parser\nrejects its declared three-segment route. Requalify this mapping when provider\nrevision changes.\n\nDiagnose webhook HTTP responses\n\n| Response | First checks | Unsafe workaround |\n\n| 400 webhook.missingheader | Exact three header names, encoding, and non-empty values | Synthesizing headers at an untrusted proxy |\n| 401 webhook.authenticationfailed | Raw bytes, time, signature, secret revision, nonce, JSON, workspace, payload fields | Logging secret or body to reveal subreason |\n| 503 webhook.storageunavailable | Replay store, event log, PostgreSQL, profile state, durable outbox | Clearing replay or outbox state |\n| 200 centrallyacknowledged | Search central event by deterministic ID | Treating it as proof of downstream consumer completion |\n| 200 durablyqueued | Inspect local outbox and central route | Asking provider to resend the same nonce |\n\nNonce admission happens before JSON validation and event persistence. A late\nfailure can leave the nonce fenced without a published event.\n\nRecover from the stage that owns the delivery. Do not change instance identity,\nevent ID, or nonce merely to bypass the fence.\n\nDiagnose storage, lease, and drain state\n\n| Symptom | First check | Recovery boundary |\n\n| Runtime storage not ready | Database URL, TLS, role, capacity, locks, and recovery report | Preserve Action, replay, event, and outbox state |\n| Admission blocked by recovery errors | Exact queued-Action and delegation records | Repair records; do not force registration |\n| Lease expired | Provider and storage readiness plus control-plane path | Stable recovery request identity |\n| Repeated heartbeat failure | Connector probe, storage probe, TLS, DID, registry identity | Keep replica unrouted |\n| Drain does not complete | In-flight gauge and original Action statuses | Wait within deadline, then preserve uncertainty |\n| Offline transition fails | Control-plane state and old lease identity | Do not start duplicate replica ID |\n\nAn empty replacement database is not recovery. It can remove durable fences\nwhile provider effects and central events remain.\n\nPrepare an escalation bundle\n\nInclude:\n• exact source revision and immutable host image digest;\n• connector version, instance, replica, tenant, workspace, and config revision;\n• redacted effective configuration and operation allowlist digest;\n• /ready body and bounded metric snapshot;\n• Action, approval, key digest, checkpoint, result, error, and receipt identities;\n• provider status and bounded request ID;\n• for webhooks, response class, header-shape results, replay scope, event ID, and outbox outcome;\n• PostgreSQL recovery, lease, drain, deployment, and incident timestamps;\n• commands and decisions already applied;\n• explicit missing evidence and unresolved uncertainty.\n\nExclude secret bytes and unredacted customer data. State whether evidence comes\nfrom source review, deployed artifact inspection, controlled execution, or live\nprovider observation.\n\nRelated documentation\n• Twenty connector configuration (../reference/configuration.md)\n• Twenty capability index (../capabilities/README.md)\n• Twenty health, observability, and recovery (../operations/health-observability-and-recovery.md)\n• Twenty webhook security, replay, and events (../reference/webhook-security-replay-and-events.md)\n• Errors and retry decisions (../../../reference/errors.md)\n"
  },
  "integrity": {
    "algorithm": "sha256",
    "sourceDigest": "552c754a6ff09e448c0b7611f86fb4720415cf413b665a3bb8c74b1e0e973d90"
  }
}
