Review a PySpark transform for silent quality failures
Run the five-check pass over a PySpark transform before it merges: null propagation, join fan-out, silent coercion, non-determinism, and missing post-write assertions. Each finding lands as severity, file:line, rule and a suggested patch.
At a glance
| When | A PySpark transform is about to be merged; A downstream table's row count changed without a code change |
|---|---|
| Where | Spark / PySpark |
| Why | Spark fails silently — nulls propagate, casts return null, and dropDuplicates keeps an arbitrary row, so the review pass is the defense before consumers see it. |
Learning objectives
- Identify the five classes of silent failure in a Spark transform
- Add pre/post row-count and null assertions to a job
- Report findings as severity, file:line, rule, patch
What you need
- A PySpark transform about to be merged
- The intended grain of the output table
- [object Object]
Steps
- Run this when a PySpark transform is about to be merged, or when a downstream table's row count changed without a code change. (from skill-spark-data-quality-review )
- Null propagation — every outer join introduces nullable right-side keys; confirm downstream code coalesces or filters them. (from skill-spark-data-quality-review )
- Join fan-out — assert key uniqueness on the intended 1-side before joining. (from skill-spark-data-quality-review )
- Silent coercion — `cast` failures return null, not errors; prefer `try_cast` and count the nulls it produces. (from skill-spark-data-quality-review )
- Non-determinism — `dropDuplicates` without a sort key keeps an arbitrary row. (from skill-spark-data-quality-review )
- Missing assertions — every write should be followed by a row-count and a null-rate check on the primary key. (from skill-spark-data-quality-review )
Check yourself
- Every write in the transform is followed by a row-count and a null-rate check on the primary key.
- Findings come back as `severity | file:line | rule | suggested patch`.
Worked example
The five-check pass, in order — from skill-spark-data-quality-review
1. Null propagation — every outer join introduces nullable right-side keys.
Confirm downstream code coalesces or filters them.
2. Join fan-out — assert key uniqueness on the intended 1-side before joining.
3. Silent coercion — `cast` failures return null, not errors. Prefer `try_cast`
and count the nulls it produces.
4. Non-determinism — `dropDuplicates` without a sort key keeps an arbitrary row.
5. Missing assertions — every write should be followed by a row-count and a
null-rate check on the primary key.
When to run it, and what comes back — from skill-spark-data-quality-review
Run this when a PySpark transform is about to be merged, or when a downstream
table's row count changed without a code change.
Output: a findings list — severity | file:line | rule | suggested patch
Sourced from
Security scan
Last sweep 2026-10-24: 0 finding(s), 0 marked as examples.
Common gotchas
- `cast` failures return null, not errors — count the nulls try_cast produces.
- `dropDuplicates` without a sort key keeps an arbitrary row.
- Every outer join introduces nullable right-side keys — confirm downstream code coalesces or filters them.
Production considerations
- Every write should be followed by a row-count and a null-rate check on the primary key.
- Report findings as `severity | file:line | rule | suggested patch` so they are actionable in a PR.
Diagram
transform review
|
|- null propagation --> outer joins --> coalesce or filter downstream
|
|- join fan-out --> assert 1-side key uniqueness
|
|- silent coercion --> try_cast + count nulls
|
|- non-determinism --> sort key before dropDuplicates
|
|- missing assertions --> row-count + null-rate after every write
Registry stats
| Verification | community · Oct 21, 2026 |
|---|---|
| Completeness | 81 |
| Trust multiplier | ×1.25 |
| Composite | 34.15 · adequate |
| Freshness | 3 days since last source check |
| Difficulty | intermediate |
| Version | 0.1.0 |
| License | CC-BY-4.0 |
| Security flags | none |
Did this solve your problem?
Review a PySpark transform for silent quality failures