This page helps you find out why an integration is not doing what you expect and fix it, working from the symptom you can see. It covers integration apps (connections, flows, triggers and runs under Setup → Platform → Integrations) and sync profiles (Setup → Platform → Sync profiles and the Sync Monitor). Almost every diagnosis starts in two places: the app's Overview and Errors pages, and the Sync Monitor.
Overview
An integration can go wrong at four points, and each leaves a different trace:
| Where it stopped | What you see | Where to look |
|---|---|---|
| Before a run was created | Nothing at all — no run, no error | The trigger's Status, the app's Active setting, the flow's active version |
| The run was refused | "Run refused: …" when you fire a trigger by hand | The message names the reason |
| The run started and failed | A run with status Failed or DeadLettered | The app's Errors page, then Step data |
| The run succeeded but the data is wrong | A Succeeded run, but records missing, duplicated or unchanged | Step data, the binding's Write Mode, the profile's Records tab |
Find the row that matches what you see, then go to the matching section under Common problems.
How xMatix handles it
Run statuses
Every execution of a flow is a run. The app's Overview page lists recent runs (Recent Runs). The Errors page shows the same list filtered to Failed and DeadLettered. Use the status filter to narrow the list.
| Status | Meaning |
|---|---|
| Pending, Running | The run has started and has not finished |
| PendingApproval | The run reached an entity write on a binding that needs approval, and is waiting for a decision |
| Succeeded | Every step finished |
| Failed | A step failed, an operator cancelled the run, or the clean-up sweep closed it |
| DeadLettered | A run that kept failing for a temporary reason ran out of automatic retries |
| Rejected | The run's approval was rejected |
A cancelled run is shown as Failed, with an OperatorCancel error. There is no separate Cancelled status in the list.
Error categories
Expand a failed run to see its latest error: a category, the time, the message and, where there is one, a Stack trace.
| Category | What it means | What happens next |
|---|---|---|
| RunFailure | A failure that would happen again on a retry, such as a bad mapping, a missing secret or a refused record | The run stays Failed. Nothing retries it. Fix the cause and Replay |
| RunFailureTransient | A temporary failure: a network error, a timeout, a 408, 429 or 5xx reply | Retried automatically (see below) |
| RetryExhausted | The automatic retries ran out | The run is DeadLettered: "Retry budget exhausted after N attempt(s); dead-lettered by retry sweeper." |
| OrphanSweeper | The run made no progress for 15 minutes | The run is closed as Failed: "Orphaned — no progress for 15 minute(s); reaped by orphan-run sweeper." |
| OperatorCancel | Someone selected Cancel run | The run is Failed: "Canceled by operator (…)." |
Automatic retries. By default a run that failed for a temporary reason is retried up to three attempts in total. The first retry waits 30 seconds, and each later wait doubles, up to one hour. Only failures from the last 24 hours are retried. Each retry is a new run linked to the one before it, and it uses the flow's current active version. Authentication failures (401, 403, a rejected credential) are not treated as temporary, so they are never retried. They keep failing until the credential is fixed.
The clean-up sweep closes runs that are Pending, Running or PendingApproval and have shown no progress for 15 minutes. It does not touch runs that are still waiting in the queue.
Step data
Step data on a run shows each step's input, output, status and error. Secret values and fields whose names look like credentials (password, token, secret, API key and similar) are shown as ***redacted***.
- Failed runs always keep step data.
- Successful runs keep it only when the flow has Capture step data switched on ("Also store each step's input and output for successful runs (failed runs always capture)").
- Step data is deleted after 30 days. An older run shows "No captured step data for this run."
What a schedule needs to fire
A Schedule (cron) or Poll trigger fires only when all of these are true:
- The trigger's Status is Active, not Paused.
- The cron expression is valid. It has six fields, seconds first (
0 */15 * * * *is every 15 minutes) and is evaluated in UTC. There is no time-zone setting on a trigger. - The app's Active setting is on.
- The flow has an active version.
- In a sandbox, the app has Allow sandbox execution on.
- Your subscription is not locked or read-only.
- The same flow has no run still in progress. If it has, the occurrence waits and fires when that run ends.
The scheduler checks triggers about every 30 seconds. Missed occurrences are not made up: after the app was inactive or the service was unavailable, the trigger fires once for the latest occurrence that fell due.
Prerequisites
- The Manage integrations capability on your security profile.
- A role on the integration app (granted on its Members page): Viewer to read runs and errors, Operator to replay, cancel and decide approvals, Admin to change triggers, flows, bindings, secrets and the app itself. See Permissions.
Procedure
Step 1 — Find the run
- Go to Setup → Platform → Integrations and open the app.
- Open Errors to see failed and dead-lettered runs, or Overview to see all recent runs.
- If you are investigating a sync profile, start on Setup → Platform → Monitoring → Sync Monitor instead. The profile's integration app is the one named on the profile; its runs are on that app's Errors page.
If there is no run at all, go to A scheduled flow never runs or Records change but no run appears.
Step 2 — Read the error
- Expand the run's row. Read the error category first, then the message.
- Use the error categories table to decide whether to wait (a transient failure inside its retry window) or act.
Step 3 — Find the step that broke
- In the run's row, select Step data.
- Read the steps from the top. The failed step has a red status and its error under the step name.
- Read the step's Input and Output:
- an authentication or connection error points at the connection or its secret;
- empty values after a Map fields step point at wrong field paths;
- a 4xx or 5xx reply from a connector points at the external system;
- a validation message means xMatix refused the record (a required field is missing, or a value is not one of the field's picklist values).
Step 4 — Fix the cause
Fix the connection, the secret, the flow or the data. A flow change needs a new version: edit it as a new draft in the flow designer, preview it with the failed run's input, then publish it. Only the active version runs.
Step 5 — Replay the run
- In the run's row, select Replay. It is offered only for runs that are Failed, Succeeded, DeadLettered or Rejected.
- Leave Payload (JSON) empty to reuse the run's archived input, or paste a JSON body to replace it. Add a Reason (optional).
- Select Replay. You see "Replay … (new run …)". The new run uses the flow's current active version, is linked to the original in Original Run, and has an Attempt one higher.
Do not replay a run that is still being retried automatically. You would process the same input twice.
Step 6 — Cancel a run that is stuck
- For a run that is Pending, Running or PendingApproval, select Cancel run.
- Confirm Cancel this run?. The run is marked Failed with an OperatorCancel error. Work that is already in progress on the server is not interrupted.
A stuck run is also closed by the clean-up sweep after 15 minutes without progress. After that it can be replayed.
Example
An administrator is told that web-shop orders stopped arriving in xMatix at about 11:00 IST.
- On the "Web shop" app's Errors page they find a row of Failed runs starting at 11:02 IST. Each has the category RunFailure. The message says the connector was refused with an authentication error.
- They open Step data on the latest run. The Connector read step failed with status 401, and the step before it is fine.
- The shop's team confirms that it changed the API key that morning. The administrator replaces the secret on the app's Secrets page under the same name, then selects Test Connection on the connection, which now passes.
- Because authentication failures are never retried automatically, the runs since 11:02 are still Failed. The order binding uses Upsert with the shop's order id, so a repeat is harmless. The administrator selects Replay on each failed run with the payload left empty, sees the new runs reach Succeeded, and checks that the morning's orders are in xMatix.
Training
Practice exercise
In a sandbox app that has Allow sandbox execution on, add a Schedule (cron) trigger to any flow with an active version, and type the five-field expression */5 * * * * into Schedule (cron expression) by hand. Save it and wait ten minutes. Then edit the trigger, select Open schedule editor, choose every 5 minutes, and save again.
Expected result: the first version saves without an error but no run appears on Overview. After you use the schedule editor, the expression becomes 0 */5 * * * * and a run appears within five minutes.
Quick reference
- No run at all: check the trigger's Status, the app's Active setting, the flow's active version and, in a sandbox, Allow sandbox execution.
- Cron has six fields, seconds first, and runs in UTC. A five-field expression saves but never fires.
- Errors = Failed + DeadLettered runs. Step data shows which step broke.
- Failed runs always keep step data, for 30 days.
- Transient failures retry three times; authentication failures never do.
- Replay for finished runs, Cancel run for unfinished ones. Both need the Operator role.
- A replay runs the current active version.
- Approve parked runs with Auto-replay parked run after approval left on.
- A conflict decision does not release the record — select Resume on the profile's Records tab.
Permissions
| Task | Needs |
|---|---|
| See Integrations, Sync profiles and the Sync Monitor | The Manage integrations capability |
| Open an app and read its runs, errors and step data | The Viewer role on the app |
| Replay, Cancel run, decide approvals | The Operator role |
| Create, edit, pause or delete connections | The Connection Manager role |
| Change triggers (including Fire now), flows, bindings, secrets, members and the app | The Admin role |
| Resolve conflicts, Resume, Reseed, Reconcile now on a sync profile | The Manage integrations capability; app roles do not apply |
A user who has the capability but no role on the app sees the app in the list, but opening it shows "You don't have access to this integration app — You're not assigned a role on this integration app. Ask an administrator to grant you at least the Viewer role." Roles are granted to security profiles, not to people, and a user gets the highest role among their active profiles. See Integrations.
Configuration
| Setting | Where | What changing it affects |
|---|---|---|
| Trigger Active | App → Triggers → Pause / Activate | Stops or resumes one trigger. Nothing that happened while it was paused is sent later |
| Schedule (cron expression) | App → Triggers → Edit | When a Schedule or Poll trigger fires. Use Open schedule editor to get a valid six-field expression |
| App Active | App → Edit | Off refuses every flow of the app: schedules are skipped, webhooks answer 404, queued runs are not executed |
| Allow sandbox execution | App → Edit, in a sandbox only | Whether the sandbox may run the app's flows |
| Run as user | App → Edit | Which records the app's flows can read and write |
| Capture step data | The flow designer | Whether successful runs keep step data (failed runs always do) |
| Write Mode | App → Entity Bindings → binding | Create, Update or Upsert — whether repeated runs update the same records |
| Require operator approval before commit | Binding → Governance & staging | Whether inbound writes wait on the Approvals page |
| Sync identity (user id) | Sync profile → settings | Which records the sync can see and change |
| Conflict policy | Sync profile, and per entity | How disagreements are settled: Field-level merge (recommended), xMatix wins, External wins, Last writer wins (lossy) or Manual |
Common problems
A scheduled flow never runs
Work down What a schedule needs to fire. The most common cause is the cron expression. The Schedule (cron expression) field checks only that it is not empty, so a five-field expression such as */15 * * * *, or any other invalid one, is saved without an error and then skipped every time the scheduler checks it. Nothing appears on the screen. Re-enter it with six fields, or select Open schedule editor, which adds the seconds field for you.
Then check the time zone. A schedule of 0 0 9 * * * fires at 09:00 UTC, which is 14:30 IST. For 09:00 IST, use 0 30 3 * * *.
Sync profile schedules are checked when you save: a five-field schedule there is refused with a message that it "expects SIX fields (seconds minutes hours day month day-of-week)".
Records change but no run appears
An Entity Event trigger leaves no run when it does not fire, so check in this order:
- The trigger shows Active and the app is active.
- The flow has an active version. An entity event for a flow without one creates no run.
- The trigger's Entity and Events match what happened. A new record is Create, not Update.
- The record matches the trigger's Filter (optional). The filter is read as the app's Run as user: if that user cannot see the record, nothing fires.
- The record was not deleted. A trigger with a filter never fires on Delete.
- The change was not written by a flow that an entity event started. Those writes do not start entity-event flows, so one flow cannot set off another through record events.
The entity's Execution Plan (Setup → Design Studio → Entities → the entity → Logic) lists the Entity Event triggers that are active for it. See Outbound integration.
"Run refused: Integration app is disabled. Re-enable the app to resume its flows."
The app's Active setting is off. Select Edit on the app, turn Active on and Save. Runs that were refused while it was off are not sent later. Fire or replay the ones that still matter.
"Sandbox tenants cannot run integration flows by default…"
You are in a sandbox and the app does not have Allow sandbox execution on. Secrets are not copied into a sandbox. First point the app's connections at test systems and enter their secrets again, then edit the app and turn the setting on. Never point a sandbox at your production systems.
"Trigger is paused (IsActive=false). Activate it before firing."
You selected Fire now on a paused trigger. Select Activate in the trigger's row first.
"You don't have access to this integration app"
You have the Manage integrations capability but none of your security profiles has a role on this app. Ask an app Admin to add your profile on the app's Members page with at least the Viewer role. New apps start with only the creator's profiles and the system administrator profile as Admin.
The connection test passes, but runs fail with authentication errors
For the HTTP REST connector this is expected. Its test proves that the address can be reached: any reply below 500 passes, including 401 and 403. Read the test result: "Connection OK — Reached … (HTTP 401)" means the address is right and the credential is wrong. Fix the secret or the headers.
Test Connection also checks only the secrets named in the connection's own settings, and a missing secret is sent as an empty value instead of failing the test. A secret used only in a step's settings is not tested at all. If a run fails with an unresolved secret, check the name in ${secret:name} against the app's Secrets page.
The Salesforce and Zoho connectors fail their test on a bad credential. For them, a passing test and failing runs usually mean the user behind the credential lacks access to those objects, or the credential was changed on one side only.
The run is Succeeded but the other system has nothing
A Connector write that gets a 4xx or 5xx reply records the reply as the step's output and does not fail the run. Open Step data on the run, read the status code and reply in the write step's output, fix the mapping or the address, and Replay the run. Successful runs keep step data only when Capture step data is on, so turn it on while you test.
Replay is refused
| Message | Cause and fix |
|---|---|
| "Run … is in non-terminal status '…'." | The run has not finished. Wait, or Cancel run first |
| "Replay requires a request body or an archived InputJson on the original run." | The original run has no stored input. Enter the payload in Payload (JSON) |
| "Original flow version … no longer exists." | The version the run used was deleted. Fire the trigger again instead |
| "No active flow version for app … flow …." | The flow has no active version. Publish one, then replay |
| "This run used values entered at run time (e.g. credentials), which are never stored. Start it again from the record instead of replaying it." | The run took values that are never saved. Start it again from the record it came from |
Inbound records are duplicating
The write is not keyed. Look at the binding's Write Mode:
- Create inserts a new record on every run.
- Upsert updates the record it can identify, either by an
idin the data or through the external-id mapping (the source system's own record id), and inserts only when it finds none. - Update never inserts. It fails with "Update write requires a resolvable id …" when it cannot find the record.
Use Upsert with the source system's stable record id. Clean up the duplicates already created, or the keyed writes keep updating one copy while the others stay stale. Sync profiles pair records through their ledger automatically, which is one reason to prefer a profile for standing synchronization.
Inbound runs park as PendingApproval and nothing is written
The binding has Require operator approval before commit on. The run stops at the entity write, and the steps before it have already run. An Operator decides on the app's Approvals page:
- Select Approve with Auto-replay parked run after approval ticked (the default). xMatix starts a new run from the parked run's archived input, and that run writes the records.
- Approving with the box cleared only records the decision. Nothing is written. To recover, wait until the clean-up sweep has closed the parked run as Failed (15 minutes after it parked), then Replay it. The approval still counts, so the replay writes the records.
- Reject closes the approval. Nothing is written.
A parked run that has already been closed by the clean-up sweep can still be approved. Approval with auto-replay still writes the records.
Every run of one app failed at the same time
Something the app's runs share has changed. In order of likelihood:
- A secret was replaced with a wrong value or deleted while connections still use it. Runs fail before the call, or with authentication errors.
- The external system revoked the credential. Authentication errors are not retried, so they continue until you fix it.
- The app was switched off. Its runs are refused with "Integration app is disabled…".
Compare the time of the first failure on Errors with the time of the change.
A partner's webhook calls are rejected
The reply code tells you why:
| Reply | Cause |
|---|---|
| 401 | The signature, API key or bearer token is missing or wrong |
| 403 | A valid token that belongs to another app or tenant |
| 404 | The address has the wrong app id or slug, the app is inactive, or no active Webhook trigger has that slug |
| 405 | The HTTP method is not one of the trigger's HTTP methods |
| 400, 415 | The body is not valid JSON, or is not JSON, form data, XML or text |
| 413 | The body is larger than 1 MB |
| 429 | Too many calls from the same caller in a short time. The caller should slow down and retry |
| 503 "Webhook secret unavailable." | The secret the trigger signs with does not exist on the app. Add it on Secrets |
A run stays Queued
A queued run waits for the background service that executes integration runs. The clean-up sweep does not close queued runs, and Cancel run is not offered for them. If runs stay Queued for more than a few minutes, contact support.
A sync profile runs but records are not syncing
In order of likelihood:
- The sync identity cannot see them. The engine reads and writes as the profile's Sync identity (user id), limited by record security. Changing it to a narrower user warns that "A narrower identity will silently stop syncing records it cannot read." Widen that user's access deliberately.
- The record is held. Find it on the profile's Records tab. Conflict, Error and Excluded (parked) records are held until someone acts: decide the conflict, fix the cause in Last error, then select Resume.
- An entity needs a reseed. The Health board's Reseed required column lists entities whose position cannot be trusted. Select Reseed on the profile's Entities tab.
- Nothing changed. A record whose content matches what was last synced is dropped as an echo and writes nothing. That is healthy.
- For push-based systems such as Tally, the site stopped reporting. There is no run and no error. Only the Sites column on the Health board shows it, and the fix is on the client's side.
I decided a conflict, but the record still does not sync
Choosing Keep xMatix, Keep external, Merged by hand or Ignore once closes the conflict and records your decision, but does not write either value. The record stays held as Conflict on the profile's Records tab until someone selects Resume on it.
To settle a conflict:
- Make the two systems agree. Edit the losing side by hand to match the side you want to keep.
- Decide the conflict, so the decision is recorded.
- On the profile's Records tab, find the record and select Resume.
On the next cycle the engine compares the record again under the profile's conflict policy. If the two sides still differ on the same field, a new conflict is raised. If the record should stop syncing for good, choose Ignore always (stop syncing this record), which parks it as Excluded until resumed.
The Cycles tab is empty and Failed streak stays at zero
The sync engine does not currently record cycles, so the profile's Cycles tab, the Last cycle columns and the Failed streak on the Health board have nothing to show. Use Watermark lag on the Health board to judge whether a profile is keeping up, and the integration app's Errors page to see failed runs.
Common questions
Does a failed integration ever affect users saving records?
No. Entity Event triggers are checked after the record has been saved, and the flow runs in the background. A failing trigger, flow or external system never undoes the save and never shows the user an error. The flip side is that a failure is visible only on the app's Errors page or the Sync Monitor, so someone has to look. Check Errors daily for apps that matter, and the Sync Monitor's Needs attention view for sync profiles.
Is it safe to just replay a failed run?
Usually, if three things are true. The run is finished and not still inside its automatic retry window. Its input is still stored, or you supply the payload. And the target can take a repeat — the write is an upsert or uses a stable key, not "create a new row". A replay runs the flow's current active version, and for an entity-event run it reads the record as it is now, not as it was. For batch runs, a replay may apply the whole batch again unless the flow records each item's result, so make sure those writes are upserts.
When should I pause and when should I switch the app off?
Pause a trigger to stop one flow: select Pause in its row. Switch the app's Active setting off to stop everything the app does: schedules are skipped, webhook calls answer 404, and queued runs are not executed. Neither deletes settings, positions or history. Runs already executing are not stopped by either; cancel those one by one. Deleting the app removes its connections, bindings, flows, triggers, runs, secrets and role assignments, and cannot be undone. Use it only to retire an integration.
Why did my scheduled run happen five and a half hours early (or late)?
Schedules run in UTC, and there is no time-zone setting on a trigger. India Standard Time is five and a half hours ahead of UTC, so an expression written for 18:00 local time fires at 23:30 IST. Subtract 5 hours 30 minutes from the local time you want: 18:00 IST is 0 30 12 * * *. The trigger's list shows the schedule as you entered it, so a mistake here is easy to miss. Check the run times on Overview against the time you intended.
Why are there gaps after an outage instead of a burst of catch-up runs?
xMatix does not make up missed schedule occurrences. When the app was inactive, the subscription was locked, or the service was unavailable, the trigger fires once for the latest occurrence that fell due and then continues normally. Sync profiles keep their own position, so their next cycle picks up every change since the last one. A flow that reads a fixed window, for example "today's orders", does not catch up on its own. Fire it by hand for the missed period, or replay the runs that failed.
