Troubleshooting
Troubleshooting
Section titled “Troubleshooting”Real failure modes and how to fix them.
Actions on the connection detail page
Section titled “Actions on the connection detail page”Open connect.destesi.io, pick a connection, and the detail page shows an Actions panel. Which buttons appear depends on the connection’s status and provider:
- Re-validate — always shown. Pings the provider with the stored credential and refreshes the connection’s status and Last validated time. Use this whenever a status looks stale or a product reported a problem you think was transient.
- Reconnect — shown when the connection is not
ACTIVEand uses OAuth. Re-runs the provider’s consent flow and lands you back on the detail page. For API-key providers (an AI provider, a stock provider, Wompi, Skydropx, and the like) this same slot reads Rotate API key and opens the key entry form instead — pasting a fresh key overwrites the stored one in place (you don’t disconnect first). - Set as default — shown only for multi-account providers when this connection isn’t already the default. Products that don’t name a specific account use the default.
- Disconnect — always shown. Removes the connection after a confirmation prompt; you can reconnect anytime.
A product says “reconnect” or a connection shows EXPIRED
Section titled “A product says “reconnect” or a connection shows EXPIRED”OAuth tokens expire. Connect refreshes them automatically when a product fetches the credential, but if the refresh itself fails — usually because you revoked Destesi’s access on the provider’s side, or the provider invalidated the grant — the connection flips to EXPIRED and products can no longer use it.
Fix: open connect.destesi.io, find the connection, and reconnect it (run the OAuth flow again). One reconnect in Connect restores it for every product in the workspace.
A connection shows ERROR
Section titled “A connection shows ERROR”ERROR means a product tried to use the credential and the provider rejected it — for example a publish hit a quota or the account lost a required permission. The credential may still be valid for other operations.
Fix: open the connection’s detail page and click Re-validate (this pings the provider and refreshes the status). If it comes back ACTIVE, the error was transient. If it stays unhealthy, Disconnect and reconnect to re-grant scopes.
An API key is rejected when I try to save it
Section titled “An API key is rejected when I try to save it”When you paste a key for an API-key provider (Pexels, ElevenLabs), Connect validates it against the provider before saving. A rejection returns invalid_api_key (HTTP 422) and nothing is stored.
Checklist:
- Copy the key exactly — no surrounding whitespace, no truncation.
- Confirm the key is for the right provider and account, and is still active in the provider’s dashboard.
- Check the key has the access the validation call needs (Connect verifies it with a lightweight authenticated request to the provider).
To replace a key on a connection that already exists, open its detail page and click Rotate API key — the new key overwrites the stored one in place once it validates.
A provider I want isn’t connectable
Section titled “A provider I want isn’t connectable”The tile tells you which case you’re in:
- The tile shows as not configured. OAuth providers only become connectable once their application credentials are set in the deployment. If you self-host, set the provider’s credentials — usually a
CONNECT_TPA_<PROVIDER>_CLIENT_ID/..._CLIENT_SECRETpair, though several providers need an extra value (see the Reference). The catalog reportsconfigured: falsefor any provider still missing credentials, and connect-api logs the dormant ones at startup. - The tile gives a reason for being unavailable. The connector normally works but is temporarily unavailable — the reason is shown rather than hidden, so you know to try again later.
The OAuth flow redirects to an unexpected page (or back to the catalog)
Section titled “The OAuth flow redirects to an unexpected page (or back to the catalog)”After approving the provider’s consent screen, Connect redirects you to a return destination. A return URL is only honored when its origin is on the configured allowlist; an unrecognized origin is silently treated as “no return URL” and you land back on your connections page rather than the flow erroring out.
If you self-host: make sure the origin you expect to return to is listed in CONNECT_WEB_URL_ALLOWLIST, and that CONNECT_OAUTH_REDIRECT_BASE_URL matches the redirect URL registered in the provider’s OAuth app (the callback path is /v1/connections/callback?provider=<id>). A mismatch here is the most common cause of a failed OAuth round-trip.
Multi-account: the picker is empty or I picked the wrong accounts
Section titled “Multi-account: the picker is empty or I picked the wrong accounts”After the consent screen for a multi-account social provider, Connect lists the accounts that grant exposes so you can choose which to add.
- Empty picker: the connected provider account doesn’t manage any downstream accounts of the needed type (for example a Google login with no YouTube channels, or a Meta login with no Instagram business accounts). Connect the right upstream account, or create the downstream account on the provider first.
- Wrong selection: Disconnect the unwanted connections from the Connect UI and re-run the flow. You can also change which account is the default with Set as default on the connection you want — products that don’t name a specific account use the default.
A server-side credential fetch returns 401 or 404
Section titled “A server-side credential fetch returns 401 or 404”These come from the controller API:
401— either the server’s controller secret is unset (so the credential, connections, and mark-error routes reject everything) or theAuthorization: Bearer <secret>you sent doesn’t match it. ConfirmIDENTITY_CONTROLLER_SECRETis set on the connect-api side and that you’re sending the same value as the bearer.404— from the credential route, this means the workspace simply has no connection for that provider. Confirm the workspace actually connected it.
An action fails
Section titled “An action fails”Actions return a small, closed set of codes — see the full table. The ones you’ll actually hit:
not_connected(409) — the workspace has no connection for that provider. Connect it, then retry.insufficient_scope(403) — the connection works but wasn’t granted a permission the action needs. Disconnect and reconnect to re-grant scopes; approving the consent screen again is what widens them.invalid_args(422) — an argument failed the action’s schema, or you sent one the action doesn’t declare. Undeclared arguments are rejected rather than quietly forwarded, so check the action’s schema in the catalog.missing_workspace(400) — you sent a token without naming a workspace. AddX-Destesi-Workspace: <slug>(or?ws=<slug>).- A non-
okresult with the provider’s own status — that isn’t an error from Connect, it means the provider answered and declined. The upstream status is in the result, which is how you tell “we couldn’t reach them” apart from “they said no”.
A trigger isn’t delivering
Section titled “A trigger isn’t delivering”Work down the chain — the failure is almost always at one specific link:
- Nothing arrives at all. The provider isn’t posting to the ingest URL. Remember Connect does not register the webhook for you: paste the ingest URL into the provider’s own webhook settings.
- Deliveries are rejected on arrival. The signature didn’t verify against the subscription’s inbound secret. Re-paste the secret at the provider; if you no longer have it, the reveal is one-time and cannot be repeated — create a new subscription.
- The subscription is paused, or the event doesn’t match. Both are acknowledged and dropped on purpose, so the provider sees success while nothing is forwarded. Check the status and the event type.
- Deliveries are recorded but failing. Your endpoint returned something other than
2xx. Open the deliveries list to see the attempts; Connect retries with growing backoff before marking one failed. unsafe_target(422) when creating. The endpoint isn’t reachable under the delivery guard — it must be HTTPS on a public address. A private, loopback, or link-local address is refused by design.- The same event arrives twice. Expected. Delivery is at-least-once; dedupe on
delivery_id.
A feature returns “disabled”
Section titled “A feature returns “disabled””Some capabilities switch off cleanly when their dependency isn’t configured, rather than half-working:
chat_disabled(503) — Connect’s agent has no model configured. The rest of Connect is unaffected.persistence_disabled(503) — chat history has no database; conversations still stream but aren’t saved.github_installs_disabled(503) — the GitHub App installations page isn’t wired up in this deployment.already_revealed(410) — trigger secrets were already revealed once. They cannot be shown again.
Federated stock search returns no results
Section titled “Federated stock search returns no results”Stock search resolves an API key per provider, preferring the workspace’s stored connection and falling back to a process-wide default key. If neither exists for a provider, that provider is skipped.
Fix: connect a stock provider in Connect, or (when self-hosting) set the fallback key for the provider you want searched — UNSPLASH_ACCESS_KEY, PEXELS_API_KEY, or PIXABAY_API_KEY. Remember per_page is capped at 30.
Still stuck
Section titled “Still stuck”- Check the connection’s status and last error in the Connect UI — both are surfaced per connection.
- Click Re-validate on the connection to get a fresh status straight from the provider.
- For self-hosted deployments, the startup log lists which providers are configured and which are dormant;
GET /readyzreports dependency health.