Building Pipelines
Testing and debugging tasks
Validate task YAML, run with --debug to inspect step input and output, and read structured Pino logs from logs/envoy.log.
Testing and debugging tasks
This guide covers the workflow for getting a task from "compiles" to "verified": validate the YAML, run with debug output against a bounded input, then inspect structured logs. Debug in layers — find the first incorrect step before touching anything downstream.
Prerequisites
- The
envoyCLI and aconnectors.yamlwith the connectors your task needs. - A task file under
tasks/.
The two output systems
Envoy separates two kinds of diagnostic output. Do not confuse them with the task's data output, which goes to stdout.
| System | Trigger | Destination | Format |
|---|---|---|---|
| Debugging | --debug flag or per-step debug: true |
stderr | Human-readable step input/config/output |
| Logging | --log-level flag |
logs/envoy.log |
Structured Pino JSON |
Steps
-
Validate the task before running it. Validation checks structure and compiles expressions — it does not call connectors or evaluate expressions against live records:
envoy validate my-taskA failing validation prints the issues and exits non-zero.
-
Run the task with debug output enabled:
envoy my-task --debug --config connectors.yamlEvery step prints its input, config, and output to stderr:
[DEBUG read_users] INPUT → undefined [DEBUG read_users] CONFIG → {"connector":"csv_source","method":"read",...} [DEBUG read_users] OUTPUT → [{"id":"1","first_name":"Alice",...},...]Payloads are truncated at roughly 2000 characters per field. Do not parse debug stderr as pipeline data.
-
To watch a single step instead of the whole pipeline, set
debug: trueon that step. It works without the global flag:- name: format type: transform debug: true config: '{ "name": input.first_name }' -
Raise the structured log level when you need more detail in the log file:
envoy my-task --log-level debug --config connectors.yamlThen inspect
logs/envoy.log— each line is one JSON object.
Log levels
--log-level accepts trace, debug, info, warn, error, and silent (default info). What gets logged at each level:
| Event | Level | Fields |
|---|---|---|
| Task started | info | task, steps |
| Task completed | info | task, items, durationMs |
| Task failed | error | task, err, durationMs |
| Step started | info | step |
| Step completed | info | step, items, durationMs |
| Step failed (ignored) | warn | step, err, errorDetail, input, config |
| Truto API call | info | method, resource, count |
| SQLite/MongoDB/CSV/YAML call | debug | method, table/collection/resource, count |
| Condition skip | debug | step |
Error entries include enriched detail — statusCode, body, response, code, and cause from API and driver errors. silent disables logging entirely.
Inspecting the pipeline with console
The console step prints items to stderr and passes them through unchanged, so you can drop it between two steps to see what flows across that boundary. It is unrelated to the task-level output key. See console.
Earlier step output is also available in any JSONata config as steps.<name>.output, which helps distinguish a source problem from a transform problem: bound the source to one known record, then compare each step's output against what you expected.
Debugging in the server and UI
Tasks run through the server keep their logs per Run. Open the Run's detail page to read them — see Tasks and task runs for where Runs live in the UI and Live run monitoring for following a Run while it executes.
Verify it worked
A task is verified when:
envoy validate my-taskexits 0 with no errors.- A
--debugrun against one known record shows the expected output at every step. logs/envoy.logshowsTask completedwith the expected item count and noStep failedwarnings you cannot explain.
Related
- console — print items mid-pipeline without changing them
- Error handling, retries, and loops — how ignored step failures are logged
- Live run monitoring — follow server-side Runs in real time
- Tasks and task runs — where Run logs appear in the UI