Skip to content

Troubleshooting data and decisions

Data and decision problems show up in five places: when the workflow is validated, when a run is submitted, when a node fails, when a run completes with something missing, and when a value is simply wrong. The first three stop with a code; the last two do not — they are the ones to read carefully.

  • The result (GET /api/v1/executions/{id}/result, get_execution_result) gives every output with its state: present (with its value or file), absent (the branch that produces it did not run — by design) or missing (the node that produces it failed). Read state before value.
  • The trace (GET /api/v1/executions/{id}/trace) lists every node with its status — completed, skipped, failed — and, for a skipped node, its skip_reason; for a failed one, its error code and message.

Validation (validate_workflow, and every save and publish) checks what can be known before running. The most frequent refusals in this area:

Code Cause Fix
CONNECTION_TYPE_MISMATCH a text wired into a number port, a JSON into a boolean give the value the right type at its source — see Values and types
CALC_UNCONNECTED_VARIABLE a variable of a Calculate expression has nothing connected connect every variable — see Calculating
JSON_SCHEMA_CATALOG_REF_UNKNOWN, JSON_SCHEMA_INVALID, JSON_SCHEMA_REMOTE_REF_FORBIDDEN the schema of a Validate JSON Schema node cannot be used see Schemas and contracts
JSON_SCHEMA_SOURCE_MISSING, JSON_SCHEMA_SOURCE_AMBIGUOUS no schema source, or more than one keep exactly one
PARAMETER_SCHEMA_INVALID a policy saved in a node (a media or quality policy) breaks its contract compare it with the contract named in the message
INVALID_SELECTION_CONFIG Select by Key has a duplicate key, an unsupported type, no cases see Choosing

A run whose inputs cannot be right is refused before it starts, with 400 validation_error: a required input is missing, or a number, boolean or JSON input received a value of another type — the text "12" for a number, "true" for a boolean. The message names the input. Send the value JSON-encoded with its real type: 12, true, {"name": "…"}. See Values and types.

A failed node stops its branch; the run ends as partial_success (or failed), and the outputs that depend on it come back missing. The code says which page to open:

Codes Page
EXTRACT_TYPE_MISMATCH, JSON_PATH_NOT_FOUND, INVALID_JSON_PATH, DEFAULT_TYPE_MISMATCH, MISSING_JSON_INPUT Reading JSON
CALC_TYPE_MISMATCH, CALC_PATH_NOT_FOUND, CALC_DIVISION_BY_ZERO, CALC_EMPTY_LIST, CALC_OVERFLOW, CALC_MISSING_INPUT Calculating
DATE_INVALID, DATE_MISSING_OTHER, INVALID_DATE_OPERATION, DATE_OUT_OF_RANGE (Date Calculation) Calculating — Dates
FORMAT_TYPE_MISMATCH, INVALID_TEXT_FORMAT (Format as Text) Turning a value into text
PREDICATE_TYPE_MISMATCH, INVALID_CONDITION_TYPE, INVALID_BOOLEAN_CONDITION Deciding
SELECTOR_NO_MATCH, MISSING_SELECTED_VALUE, MISSING_DEFAULT_VALUE, INVALID_SELECTOR_TYPE Choosing
QUALITY_GATE_FAILED, INVALID_QUALITY_CHECK, DUPLICATE_CHECK_ID Quality checks
JSON_SCHEMA_VALIDATION_FAILED, JSON_SCHEMA_DOCUMENT_MISSING Schemas and contracts
ROW_CONVERSION_FAILED, AMBIGUOUS_TABLE, TABLE_NOT_FOUND, DATASET_COLUMN_NOT_FOUND, EMPTY_DATA Spreadsheets and datasets
BUNDLE_MANIFEST_INVALID, INVALID_MANIFEST, FORBIDDEN Asset bundles

Three of them are worth recognising on sight:

  • PREDICATE_TYPE_MISMATCH, CALC_TYPE_MISMATCH, EXTRACT_TYPE_MISMATCH — a value arrived with another type than the step expects, almost always a number or a boolean written as text in a JSON document. Set Extract’s expected_type, so the mismatch is reported where the value is read.
  • ROW_CONVERSION_FAILED on a number column of a CSV — the numbers are written with a decimal comma and the file was read without its locale. Inspect the file and set locale (it-IT, de-DE…).
  • QUALITY_GATE_FAILED or JSON_SCHEMA_VALIDATION_FAILED — the check did its job in fail mode. When a rejection is a normal outcome, use route: the run completes and the rejected branch is skipped.

The run completed, but an output is absent

Section titled “The run completed, but an output is absent”

An absent output is not an error: the branch that produces it did not run, on purpose. The trace says why, node by node — see Branches and absence:

skip_reason What happened If you expected the output
branch_rejected a decision upstream cut the branch: a Filter that rejected, Extract with on_missing: absent and the field missing, Select by Key with no match, a Quality Gate or Validate JSON Schema in route that rejected follow the branch back to the decision and read its inputs: the condition, the field, the key, the checks, the errors
required_input_absent a required port received nothing, because an optional input was left empty supply the input, or connect it to an optional port
optional_input_not_provided an optional input node that nobody filled supply it if it matters
upstream_absent an output node whose source produced nothing look at the source node

Two patterns explain most surprises:

  • “Nothing after the Filter ran.” The Filter rejected: its condition was false (or true with Invert). Look at the Predicate that feeds it and at the values the Predicate compared.
  • “The step after Combine Conditions was skipped.” One of its conditions did not arrive — it was rejected upstream — and a condition is never guessed.
  • A price a hundred times too large or too small. Numbers were read in the wrong language. A CSV is read with its locale; a number that does not fit it stays text instead of changing, so a wrong value comes from a wrong declared locale, not from a guess. Inspect the file and compare the profile’s sample with the file.
  • A code lost its zeros or changed. An ISBN, an EAN, a postcode are codes: map them to a text output, never to a number.
  • A total that is off by a cent. Round once, at the end, with round(x, 2) or decimals, not at every step.
  • A decision that goes the wrong way. Comparisons are exact: "Chair" is not "chair" for a Predicate, and Select by Key ignores case unless caseSensitive is on. Keep the two in step.
  • An AI answer that looks right but breaks a later step. Check it with a schema right after the AI step, and read the fields from Normalized JSON.

A deferred estimate means the number of iterations is known only at run time: a list produced inside the workflow, or a bundle. The cost per item is known; the count is not — and deferred is not free. For a table, estimate with the same file (Data Input counts its rows exactly). For a bundle or a runtime list, run with admission_limits so a larger input than expected stops before it spends more than you meant.