Validate before you run
The question for this lesson: you’ve edited a 200-line pipeline. Before you run it over a million rows, how do you check it’s correct, without waiting for the whole run?
What you’ll be able to do
Section titled “What you’ll be able to do”- Use
--dry-runto validate config structure and declared types without processing data, and know what it leaves for the real run. - Use
--explainto print the execution plan and read it. - Decode a diagnostic E-code with
explain --code.
Check without running: --dry-run
Section titled “Check without running: --dry-run”clinker run customer_etl.yaml --dry-run--dry-run parses your YAML, checks the config’s structure, validates your declared schema
types, and resolves the output paths, then stops, without reading a single data row. If a
required field is missing or a schema type doesn’t exist, you find out in a second.
Planning-only --dry-run validates the complete DAG and typechecks CXL against
the declared schemas. It catches dangling input: references, unknown fields
or methods, and incompatible types before reading records. It cannot prove that
the actual file’s bytes satisfy the schema or that your business rule is right.
🌱 New here? — planning versus execution
Planning uses the pipeline and its declarations. To exercise real input, add
-n 5: this reads at most five records per Source, evaluates the pipeline, and
serializes preview bytes to stdout without opening configured Sink paths.
--dry-run-output preview.csv selects an explicit preview file. A sample’s
output-row count may differ after filters, aggregates, joins, or fan-out.
See the shape: --explain
Section titled “See the shape: --explain”clinker run customer_etl.yaml --explain--explain prints the execution plan in labelled sections (the CXL it compiled, the node
graph, and how data flows), so you can confirm the pipeline does what you think before you run
it. The full output is long; here are the three sections you’ll read most (trimmed):
=== Execution Plan ===
Mode: StreamingTransforms: 1Output projections: 1DAG nodes: 3
=== CXL Expressions ===
Transform 'tagged': emit is_active = status == "active"
=== DAG Topology ===
● [source] customers │ [transform] tagged │ [sink] resultsDecode a diagnostic: explain --code
Section titled “Decode a diagnostic: explain --code”When a run or dry-run fails, it prints an E-code. You don’t have to guess what it means; look any code up directly, with no config needed:
clinker explain --code E105That prints a full explanation of the diagnostic: what it means, an example that triggers it,
and how to fix it. E105, for instance, is “Channel binding references undeclared config
key”: a channel file bound a config key the target pipeline never declared. The point isn’t to
memorize codes. Whenever a run prints one, explain --code turns it into a plain
explanation on the spot.
Use: validate a pipeline
Section titled “Use: validate a pipeline”Run --dry-run on this one. Predict whether it passes, then check.
> output appears here — predict, then run
Modify: break it on purpose
Section titled “Modify: break it on purpose”Now make --dry-run fail in two different ways. In the runner above, try
two changes, one at a time, and predict the outcome of each before you re-run.
// quick check
What does `--dry-run` validate before reading any data?
Planning checks wiring and CXL against declared schemas without reading records. Actual data conversion and business-output correctness require execution.
Create: pre-flight a pipeline you build
Section titled “Create: pre-flight a pipeline you build”Now put the tools together on a pipeline of your own. Author a small one from scratch: a csv
source with a declared schema, one transform that emits a computed field, and an output.
Then run the full pre-flight before any real run:
clinker run mine.yaml --dry-run: does the config compile, and do the declared types check out?clinker run mine.yaml --explain: does=== DAG Topology ===show the nodes wired the way you intended, and does=== CXL Expressions ===show the formula you meant?- Fix anything it surfaces, then run for real.
Predict, before you run: if you misspell a transform’s input:, both
--dry-run and --explain reject the dangling reference during planning.