Published

Pipeline ProblemReport — Codes Catalog

Connect any source, model it as an ontology, transform it, and operationalize it, analytics, automation and machine learning, under one governed, self-hostable roof. --- Most teams stitch the...

Pipeline ProblemReport — Codes Catalog

Phase 7 — every transform-path issue (compile error, runtime fallback, type drift, capability gap, …) flows through the canonical ProblemReport shape defined in lib/pipelines/problems.ts. This document is the authoritative join key for the persisted pipeline_run_problems rows, the /api/pipelines/<id>/problems API response, the future telemetry dashboard, and any in-product help links.

Codes are stable. Once a code is emitted to a user, its name is frozen. Renames require a migration that translates old persisted rows. New codes can be added freely (each phase introduces a few).


Reading the entries

FieldMeaning
CodeStable enum value emitted in ProblemReport.code.
Severityerror blocks compile/run; warning surfaces in UI but doesn't block; info is purely informational.
DimensionOne of compile / schema / param / type-guard / null-handling / runtime-fallback / drift / dependency. Mirrors the audit rubric.
CauseWhat user state / data triggers the problem.
FixConcrete next action for the user.
PhaseWhich audit phase added the code.

Generic / fall-through

COMPILE_ERROR — error · compile

  • Cause: A compiler threw a non-structured error (anything that isn't already a ProblemReportError). Catch-all wrapper applied by compileStack.
  • Fix: Read the message. Most common: malformed user expression, unknown transform parameter shape, unexpected null in a required field.
  • Phase: 1

MISSING_COMPILER — error · compile

  • Cause: The widget references a transform name (widget.type) that has no entry in COMPILERS. Usually means a deprecated transform or a typo in persisted state.
  • Fix: Remove the widget, or add the transform's compiler module.
  • Phase: 1

Param validation

MISSING_PARAM — error · param

  • Cause: A required field is empty or missing from the widget params.
  • Fix: Fill in the field.
  • Phase: 1

INVALID_PARAM_VALUE — error · param

  • Cause: A field's value is the wrong type or out of range (e.g. Sample: fraction not in (0, 1]).
  • Fix: Adjust the value to the allowed range / format.
  • Phase: 1

Schema / column references

COLUMN_NOT_FOUND — error · schema

  • Cause: A column name in the widget params doesn't exist in the input schema. Usually upstream schema drift (an upstream widget renamed/dropped the column) or a stale param after editing.
  • Fix: Pick a different column, or fix the upstream widget so the column survives.
  • Phase: 1

OUTPUT_COLLISION — error · schema

  • Cause: The widget's output column name collides with an existing column in the input schema. addColumnStep and replaceColumnStep both check.
  • Fix: Pick a different output name, drop the colliding column upstream, or use a prefix.
  • Phase: 3

Type guards

COLUMN_GROUP_MISMATCH — error · type-guard

  • Cause: A field declares acceptsGroups: ['Numeric'] (etc.) but the picked column belongs to a different group. Usually a mismatch after schema drift.
  • Fix: Pick a column of the required group, or apply a Cast first.
  • Phase: 1

COLUMN_TYPE_MISMATCH — error · type-guard

  • Cause: Stricter than COLUMN_GROUP_MISMATCH — a field requires specific base types within a group (e.g. Bit shifts need Short / Integer / Long, not Decimal).
  • Fix: Pick a column of the allowed base type, or Cast first.
  • Phase: 2

FN_GROUP_MISMATCH — error · type-guard

  • Cause: An aggregation function requires a specific group (e.g. Sum / Avg / Stddev / Variance / Median / Percentile need a Numeric column) but the picked column is a different group. Used by Aggregate, Pivot, Rollup, Window.
  • Fix: Pick a Numeric column, or apply a Cast.
  • Phase: 3

TYPE_HOMOGENEITY — error · type-guard

  • Cause: A multi-column op (Coalesce, Least, Greatest) was given columns from incompatible type groups. Postgres requires a common type.
  • Fix: Apply a Cast to unify the types before the widget.
  • Phase: 3

INVALID_LITERAL_CAST — error · param

  • Cause: A literal value is not representable as the target base type (e.g. 'abc' cast to Integer in Fill nulls).
  • Fix: Provide a valid literal of the required type.
  • Phase: 1

Pattern validation

INVALID_REGEX — error · param

  • Cause: The regex pattern in Replace (regex mode), Match regex, or Regex extract failed JS regex parsing. POSIX (Postgres) and PCRE (JS) overlap on most patterns; lookaheads and named groups may differ.
  • Fix: Fix the regex syntax. Test in a JS regex playground first (close approximation).
  • Phase: 3

Dependency

MISSING_CAPABILITY — error · dependency

  • Cause: The transform requires an optional Postgres extension or a minimum PG version that isn't available in the workspace runtime. Detected via pg_extension probe at boot.
  • Fix: Install the extension (PostGIS, pgcrypto) or upgrade Postgres (PG14+ for pg_input_is_valid). The picker UI dims affected transforms when caps are missing.
  • Phase: 5

Joins (Phase 1 — Pipeline Joins MVP)

Emitted by lib/pipelines/joinSpec.ts → validateJoinSpec and stamped on the synthetic widget id __join__. The validator runs before the join compiler; any error here means no SQL is emitted and the materialise tx is never opened.

JOIN_EMPTY_CONDITIONS — error · param

  • Cause: A non-cross join (inner / left / outer / anti / semi) has zero match conditions. Cross join is the only type allowed to omit the predicate.
  • Fix: Add at least one match condition (left column = right column), or switch the Join type to Cross join.
  • Phase: 1

JOIN_COLUMN_NOT_FOUND — error · schema

  • Cause: A column referenced in a match condition or in the output projection no longer exists on its side's schema. Common after a left/right dataset is renamed upstream or its schema drifts.
  • Fix: Re-pick the missing column, or rerun the upstream pipeline that produces it.
  • Phase: 1

JOIN_TYPE_MISMATCH — error · type-guard

  • Cause: Two columns paired in a match condition belong to incompatible compatGroups (e.g. joining a String column to a Long). Postgres would either fail at runtime or silently coerce in surprising ways.
  • Fix: Cast one side to a compatible type before joining (e.g. apply a Cast transform upstream).
  • Phase: 1

JOIN_OUTPUT_COLLISION — error · schema

  • Cause: Two projected output columns share the same name even after the right prefix is applied. Anti / semi joins skip this check (left-only output).
  • Fix: Set or change the right prefix to disambiguate, or deselect one of the two clashing columns.
  • Phase: 1

JOIN_CARDINALITY_EXCEEDED — error · runtime-fallback

  • Cause: A CROSS join's pre-flight estimate (|left| × |right|) exceeds PIPELINE_JOIN_MAX_OUTPUT_ROWS (default 10,000,000). Reject path — no rows are materialised. Only fires for joinType: 'cross'; the other shapes are filter-bounded by their match conditions and don't carry this risk.
  • Fix: Filter the inputs upstream (a Sample or Filter rows transform), or switch to inner / left / outer with a match condition. Workspaces with genuine large-cartesian use cases can raise the cap via the env var.
  • Phase: 1

JOIN_RESULT_TRUNCATED — warning · runtime-fallback

  • Cause: A CROSS join's SQL-level LIMIT (N+1) backstop clamped the result. Pre-flight passed but the inputs grew between the count estimate and execution (concurrent writes, stale stats). The materialised output is partial — first JOIN_MAX_OUTPUT_ROWS rows; subsequent rows were not written.
  • Fix: Re-apply once the inputs stabilise, or filter them upstream to land within the budget. Downstream consumers should treat the output as truncated until the next clean apply.
  • Phase: 1

Cross-reference: which transforms emit which codes

CodeTransforms
MISSING_COMPILER(any transform whose compiler is removed)
MISSING_PARAM(any transform with required fields)
INVALID_PARAM_VALUESample, bit shifts, numeric range checks
COLUMN_NOT_FOUND(any transform that references columns)
OUTPUT_COLLISIONAll addColumnStep / replaceColumnStep callers (~125 transforms)
COLUMN_GROUP_MISMATCHGeneric — surfaced via assertColumnGroup
COLUMN_TYPE_MISMATCHBit shift left / Bit shift right
FN_GROUP_MISMATCHAggregate, Pivot, Rollup, Window
TYPE_HOMOGENEITYCoalesce, Least, Greatest
INVALID_LITERAL_CASTAdd constant column, If condition, Map values, Fill nulls
INVALID_REGEXReplace (regex mode), Match regex, Regex extract
MISSING_CAPABILITY16 Geo (postgis) + 3 Hash (pgcrypto) + 3 IPv4/IPv6 (pg14)
JOIN_EMPTY_CONDITIONSInner / Left / Outer / Anti / Semi joins (Cross is exempt)
JOIN_COLUMN_NOT_FOUNDAll 6 join types (condition columns + projected columns)
JOIN_TYPE_MISMATCHAll 6 join types (pairs in match conditions, compatGroup check)
JOIN_OUTPUT_COLLISIONInner / Left / Outer / Cross (Anti / Semi return left-only)
JOIN_CARDINALITY_EXCEEDEDCross join only (other shapes are filter-bounded)
JOIN_RESULT_TRUNCATEDCross join only

Adding a new code

  1. Add the literal to ProblemCode in lib/pipelines/problems.ts. Order: keep grouped by dimension.
  2. Update the relevant dimension enum if a new category emerges.
  3. Add an entry to this document under the right section. Include cause + fix + phase.
  4. Update the pipeline_run_problems.dimension CHECK constraint if a new dimension was added (migration required).
  5. Update the cross-reference table at the bottom.