Skip to content

Trace viewer ​

When something looks wrong in production — an activity not showing up where you expected, the wrong agent attributed, a value that should be filled but isn't — the trace viewer is where you start. It shows you exactly what happened on a specific run of the processor against a specific source model: which instructions ran, what each one received, what it produced.

Finding an execution ​

Every time a source delivers a record to a processor, SalesDash records the run as a processor execution. They're listed under Providers → Processor Executions, sorted with the most recent first. Each row shows the processor that ran, the source model it ran against, when it ran, and whether it succeeded.

Click any row's View trace link to open the trace viewer for that execution.

The Provider processor executions list, with one row per (source model × processor) run.

What you see ​

The trace viewer is the same three-panel layout as the Spec Builder, with execution data overlaid on it.

Trace mode: the source model's actual values on the left, per-instruction execution status in the centre, the selected instruction's resolved values on the right.

  • Left panel — same source model, constants, and enrichments as in edit mode, but the source model is now expanded with the actual values the execution worked with. You can drill into any field to see what it held at runtime, including nested enrichments.
  • Centre panel — the same list of instructions, but each one is annotated with what happened when it ran: found / updated next to upserts, the chosen branch on an if_else, the iteration count on a for_each, and any error messages in red.
  • Right panel — when an instruction is selected, the inspector shows the same form as in edit mode but pre-filled with the resolved values. Expressions inside the form expand into a tree: you see exactly what each sub-expression returned, all the way down to the literals and variables.

The expression tree on the right is what you'll come back to most often when debugging — when an external_id or activity_type doesn't look right in production, expanding the expression in trace mode shows you which sub-expression produced the wrong value.

Close-up of the inspector showing an external_id built with  — the literal  and the resolved value of  shown alongside the inputs.

For for_each blocks specifically, the inspector's top shows the iteration count and a stepper. Move through iterations to see the body's annotations and variable values for each item — useful when one specific iteration failed and the rest succeeded.

A  block in trace mode showing iteration 1 of 11 with stepper controls in the inspector.

Copying values and paths ​

Everything in the source model tree on the left is copyable, which saves retyping a value into a filter in the source system or a path into a formula:

  • Click a field's name to copy its path — payload.customer.email. That is exactly what goes inside the braces of a variable reference, so you can paste it straight into an expression field as {payload.customer.email}.
  • Click its value to copy the value itself, in full — including the part cut off by the column width.
  • Names of groups — an object or a list, anything with a ▸ beside it — expand and collapse instead; only the fields inside them have a path worth copying.

A short confirmation appears in the row when the copy succeeded. Text in the tree can also be selected with the mouse in the normal way; selecting a stretch of text never triggers a copy or collapses the row you were selecting in.

Test button: manual runs ​

The Test button in the topbar lets you run the processor against a historic source model right now, without waiting for the source to deliver the same record again. Pick the historic record you want to test against (using the Trace Schema picker in the left panel of edit mode), make whatever changes you want to the spec, save, and click Test. The processor runs the current saved spec against that record and produces a fresh trace — useful for verifying that a fix actually changes the outcome before you enable the processor for live data.

This is also how you do the first run of a brand-new processor: configure the source to deliver records, wait for one to come through, then keep iterating on the spec by replaying that record until the trace shows what you want.

Replaying executions from the list ​

Once a fix is saved, you usually want it applied to the records that came through while the spec was wrong, not only to the one you tested against. The processor executions list does this.

  • Replay on a row runs the processor's current saved spec against that execution's source model, exactly as the Test button does. A notification links to the trace of the new execution.
  • To replay many at once, filter the list (for example by processor and by the status Error), select the executions and choose Replay from the bulk actions. The replays run in the background. Each one shows up in the list as a new execution once it has run.
  • To replay a period, such as everything a webhook source delivered this week, use the Created at filter. Both dates count as whole days, and either one can be left empty. Then select all the matching executions, not only the visible page, and replay them.

A replay runs the same processor again, with its spec as it is now, and writes for real, exactly like a new delivery of the record. Processors are built so that processing the same record twice is safe, so it does not matter whether a later execution of the same record exists. When a bulk replay includes several executions of the same record, they run oldest first, so the record ends up as its most recent delivery described it.

An execution can only be replayed while its trace is still stored. In a bulk replay, an execution that can't be replayed is skipped without a message. That is an execution whose trace is gone, whose personal data was masked, or whose processor is no longer linked to the source. It also happens when the provider's API fails while the replay fetches enrichments, or when a live delivery of the same record is still being processed. Replay it from its row to see the reason.

Personal-data masking ​

Source models that include end-customer personal data have those fields masked in the trace viewer — you'll see redacted placeholders rather than the actual values. The validator already blocks specs from referencing those fields, and the masker is a second layer: even raw source-record values that pass through the trace pipeline never expose personal data in the viewer.