Skip to content

Errors API

The weevr.errors module defines the exception hierarchy used throughout the framework. All weevr-specific exceptions inherit from a common base class for consistent error handling.

weevr.errors

Error handling for weevr.

__all__ = ['WeevError', 'ConfigError', 'ConfigParseError', 'ConfigSchemaError', 'ConfigVersionError', 'VariableResolutionError', 'ReferenceResolutionError', 'InheritanceError', 'ModelValidationError', 'ExecutionError', 'ExportError', 'SparkError', 'StateError', 'HookError', 'LookupResolutionError', 'DataValidationError', 'WarpEnforcementError', 'SchemaDriftError'] module-attribute

ConfigError

Bases: WeevError

Base exception for configuration-related errors.

__init__(message, cause=None, file_path=None, config_key=None)

Initialize ConfigError.

Parameters:

Name Type Description Default
message str

Human-readable error message

required
cause Exception | None

Optional underlying exception

None
file_path str | None

Path to the config file where the error occurred

None
config_key str | None

Specific config key that caused the error

None

__str__()

Return string representation with context.

ConfigParseError

Bases: ConfigError

Raised when a YAML config file cannot be read or parsed.

Common triggers include missing files, empty content, invalid YAML syntax, non-dictionary top-level structures, and malformed config_version fields.

ConfigSchemaError

Bases: ConfigError

Raised when config structure does not match the expected Pydantic schema.

This covers missing required fields, unknown config types, parameter type mismatches, and invalid format for typed parameters (dates, timestamps).

ConfigVersionError

Bases: ConfigError

Raised when config_version specifies an unsupported major version.

weevr validates that the declared version is compatible with the current parser. Only major version 1.x is supported.

DataValidationError

Bases: WeevError

Raised when a fatal-severity validation rule has failing rows.

When any row fails a validation rule declared with severity: fatal, the thread aborts immediately without writing data. Downgrade to severity: error to quarantine failing rows instead of aborting.

ExecutionError

Bases: WeevError

Base exception for execution-time errors.

Carries optional execution context to pinpoint where a failure occurred within a thread pipeline.

__init__(message, cause=None, thread_name=None, step_index=None, step_type=None, source_name=None)

Initialize ExecutionError.

Parameters:

Name Type Description Default
message str

Human-readable error message.

required
cause Exception | None

Optional underlying exception.

None
thread_name str | None

Name of the thread where the error occurred.

None
step_index int | None

Zero-based index of the pipeline step that failed.

None
step_type str | None

Step type key (e.g. "filter", "join") that failed.

None
source_name str | None

Source alias that caused the error.

None

__str__()

Return string representation with execution context.

ExportError

Bases: ExecutionError

Raised when an export write fails with on_failure: abort.

Carries export-specific context to identify which export failed and what format was being written.

__init__(message, cause=None, thread_name=None, export_name=None, export_type=None)

Initialize ExportError.

Parameters:

Name Type Description Default
message str

Human-readable error message.

required
cause Exception | None

Optional underlying exception.

None
thread_name str | None

Name of the thread where the error occurred.

None
export_name str | None

Name of the export that failed.

None
export_type str | None

Format type of the export (e.g. "parquet", "csv").

None

__str__()

Return string representation with export context.

HookError

Bases: ExecutionError

Raised when a hook step fails with on_failure: abort.

Carries hook-specific context to identify which step failed and in which phase of the weave lifecycle.

__init__(message, cause=None, hook_name=None, hook_type=None, phase=None)

Initialize HookError.

Parameters:

Name Type Description Default
message str

Human-readable error message.

required
cause Exception | None

Optional underlying exception.

None
hook_name str | None

Name of the hook step that failed.

None
hook_type str | None

Step type key (e.g. "quality_gate", "sql_statement").

None
phase str | None

Execution phase ("pre" or "post").

None

__str__()

Return string representation with hook context.

InheritanceError

Bases: ConfigError

Raised when the configuration inheritance cascade fails.

Reserved for failures during the loom → weave → thread default merging process. Not currently raised in v1.0.

LookupResolutionError

Bases: ConfigError

Raised when a thread references a lookup not defined in the weave.

This is a fail-fast validation error caught during config resolution, before any data is read or threads are executed.

ModelValidationError

Bases: ConfigError

Raised when a fully resolved config fails to hydrate into a typed model.

This occurs after variable resolution and inheritance, when the concrete values are validated through the Pydantic domain model (Thread, Weave, or Loom). Semantic constraints that span multiple fields are checked here.

ReferenceResolutionError

Bases: ConfigError

Raised when a ref: entry cannot be loaded or creates a circular chain.

Common causes include missing referenced files, incorrect relative paths, and circular reference chains between weaves or threads.

SchemaDriftError

Bases: ExecutionError

Raised when schema drift is detected in strict mode with on_drift: error.

Carries the drift report with details about which extra columns were found and the configured drift handling mode.

__init__(message, cause=None, thread_name=None, drift_report=None)

Initialize SchemaDriftError.

Parameters:

Name Type Description Default
message str

Human-readable error message.

required
cause Exception | None

Optional underlying exception.

None
thread_name str | None

Name of the thread where the error occurred.

None
drift_report DriftReport | None

DriftReport instance with drift details.

None

__str__()

Return string representation with drift info.

SparkError

Bases: ExecutionError

Raised for Spark API-level failures during thread execution.

Intended for errors originating from PySpark operations (reader failures, write exceptions, catalyst errors). Reserved for future use — v1.0 uses ExecutionError for all runtime failures.

StateError

Bases: ExecutionError

Watermark state persistence errors.

Raised when watermark state cannot be read from or written to the configured store. Carries store_type context in addition to the standard execution context fields.

__init__(message, cause=None, thread_name=None, store_type=None)

Initialize StateError.

Parameters:

Name Type Description Default
message str

Human-readable error message.

required
cause Exception | None

Optional underlying exception.

None
thread_name str | None

Name of the thread where the error occurred.

None
store_type str | None

Watermark store type (e.g. "table_properties", "metadata_table").

None

__str__()

Return string representation with store context.

VariableResolutionError

Bases: ConfigError

Raised when a ${variable} reference cannot be resolved.

This occurs when a variable placeholder has no matching entry in the parameter context and no default value (${var:-default}) is provided.

WarpEnforcementError

Bases: ExecutionError

Raised when warp contract enforcement finds violations.

Carries the list of enforcement findings (missing columns, type mismatches, nullable violations) that caused the failure.

__init__(message, cause=None, thread_name=None, findings=None)

Initialize WarpEnforcementError.

Parameters:

Name Type Description Default
message str

Human-readable error message.

required
cause Exception | None

Optional underlying exception.

None
thread_name str | None

Name of the thread where the error occurred.

None
findings list[dict[str, str]] | None

List of enforcement findings (dicts with type, column, etc.).

None

__str__()

Return string representation with findings count.

WeevError

Bases: Exception

Base exception for all weevr errors.

__init__(message, cause=None)

Initialize WeevError.

Parameters:

Name Type Description Default
message str

Human-readable error message

required
cause Exception | None

Optional underlying exception that triggered this error

None

__str__()

Return string representation of the error.


Error Troubleshooting Catalog

This section provides actionable guidance for every exception class in weevr.errors. Each entry explains when the error is raised, common causes, and how to resolve it.

Exception hierarchy

WeevErrorConfigErrorExecutionErrorDataValidationErrorConfigParseErrorConfigSchemaErrorConfigVersionErrorVariableResolutionErrorReferenceResolutionErrorInheritanceErrorModelValidationErrorLookupResolutionErrorSparkErrorStateErrorHookErrorExportErrorWarpEnforcementErrorSchemaDriftError

WeevError

Base exception for all weevr errors. Not raised directly — catch this to handle any weevr-specific exception.

from weevr.errors import WeevError

try:
    result = ctx.run("daily.loom")
except WeevError as e:
    print(f"weevr error: {e}")
    if e.cause:
        print(f"  caused by: {e.cause}")

Related: All exceptions below inherit from WeevError.


ConfigError

Base exception for configuration-related errors. Carries optional file_path and config_key context.

Common causes:

  • Project directory missing .weevr extension
  • Unsupported file extension (not .thread, .weave, or .loom)
  • Declared config name does not match filename stem
  • Circular dependency detected in weave thread ordering
  • Invalid foreach block structure in step list

Resolution:

  1. Verify the project directory ends with .weevr
  2. Check that all config files use typed extensions
  3. Ensure the name: field matches the filename (or omit it)

Example:

# This file is saved as "orders/fact_orders.thread"
# but declares a different name — triggers ConfigError
name: wrong_name  # should be "fact_orders" or omitted
config_version: "1.0"
sources:
  orders:
    type: delta
    alias: raw.orders

Related: Configuration Keys


ConfigParseError

Raised when a YAML file cannot be read or parsed.

Common causes:

  • File not found at the specified path
  • Empty or null YAML content
  • Invalid YAML syntax (indentation, special characters)
  • YAML content is not a dictionary (e.g., a list or scalar)
  • Missing required config_version field
  • config_version not in "major.minor" format

Resolution:

  1. Verify the file exists at the expected path
  2. Validate YAML syntax with a linter or yamllint
  3. Ensure the file starts with key-value pairs (a YAML mapping)
  4. Add config_version: "1.0" as the first field

Example:

# Invalid — missing config_version
sources:
  orders:
    type: delta
    alias: raw.orders

# Fixed
config_version: "1.0"
sources:
  orders:
    type: delta
    alias: raw.orders

Related: YAML Schema: Thread


ConfigSchemaError

Raised when the configuration structure does not match the expected schema.

Common causes:

  • Required fields missing (e.g., sources or target in a thread)
  • Unknown config type passed to validation
  • Required parameter not supplied at runtime
  • Parameter value does not match declared type (wrong type for int, bool, date, etc.)
  • Date parameter not in YYYY-MM-DD format
  • Timestamp parameter not in ISO 8601 format

Resolution:

  1. Compare your config against the YAML Schema Reference for required fields
  2. Check that all declared parameters are supplied with correct types
  3. Use YYYY-MM-DD for date parameters and ISO 8601 for timestamps

Example:

# Invalid — thread missing required 'target' field
config_version: "1.0"
sources:
  orders:
    type: delta
    alias: raw.orders
steps:
  - filter:
      expr: "status = 'active'"
# Missing: target

# Fixed — add target
target:
  path: Tables/stg_orders

Related: Configuration Keys, YAML Schema: Thread


ConfigVersionError

Raised when the config_version is not supported.

Common causes:

  • Major version does not match the supported version
  • Unknown config type for version validation

Resolution:

  1. Set config_version: "1.0" — this is the only supported version
  2. Check that the file extension matches the intended config type

Example:

# Invalid — unsupported version
config_version: "2.0"
sources:
  orders:
    type: delta
    alias: raw.orders

# Fixed
config_version: "1.0"

VariableResolutionError

Raised when a ${variable} reference cannot be resolved and has no default value.

Common causes:

  • Variable referenced in config but not supplied in runtime parameters
  • Typo in variable name
  • Missing params: declaration in parent config

Resolution:

  1. Supply the missing parameter at runtime: ctx.run("daily.loom", params={"env": "prod"})
  2. Add a default value in the config: ${env:-dev}
  3. Check for typos in the variable name

Example:

# This will fail if "env" is not supplied at runtime
sources:
  orders:
    type: delta
    alias: ${env}.raw.orders

# Fixed — add a default value
sources:
  orders:
    type: delta
    alias: ${env:-dev}.raw.orders

Related: Config Resolution


ReferenceResolutionError

Raised when a referenced config file cannot be loaded or when circular references are detected.

Common causes:

  • Referenced file does not exist at the resolved path
  • Circular reference chain (A references B which references A)
  • Incorrect relative path in ref: entries

Resolution:

  1. Verify the referenced file exists relative to the project root
  2. Check for circular ref: chains between weaves and threads
  3. Use typed extensions in references (.thread, .weave, .loom)

Example:

# Weave referencing a non-existent thread
config_version: "1.0"
threads:
  - ref: orders/fact_orders.thread  # file must exist at this path

# Circular reference — thread A depends on thread B's target,
# and thread B depends on thread A's target

Related: Thread, Weave, Loom


InheritanceError

Raised when the configuration inheritance cascade fails. Reserved for future use — not currently raised.

Intended for: Failures during loom → weave → thread default merging.


ModelValidationError

Raised when the fully resolved configuration fails to hydrate into a typed model (Thread, Weave, or Loom).

Common causes:

  • Semantic validation failure after variable resolution
  • Field values that pass schema validation but fail model constraints
  • Inconsistent combinations of settings that are only detectable after all variables are resolved

Resolution:

  1. Check the error message for the specific field that failed
  2. Verify that resolved variable values produce valid combinations
  3. Run with mode="validate" to test config without executing

Example:

# Validate config without running — catches ModelValidationError early
result = ctx.run("daily.loom", mode="validate")

LookupResolutionError

Raised when a thread references a lookup name that is not defined in the weave's lookups map. This is a fail-fast validation error caught during config resolution, before any data is read.

Common causes:

  • Typo in the lookup field of a source definition
  • Thread uses lookup: foo but the weave does not declare a foo entry in its lookups block
  • Thread was moved to a different weave that does not define the lookup

Resolution:

  1. Check that the lookup name in the thread's source matches a key in the weave's lookups block
  2. Verify the thread is referenced by the correct weave
  3. If the lookup was renamed, update all thread references

Example:

# Thread source references a lookup
sources:
  products:
    lookup: dim_product   # must exist in the weave's lookups

# Weave must define it
lookups:
  dim_product:            # matches the thread's lookup reference
    source:
      type: delta
      alias: silver.dim_product

Related: YAML Schema: Weave


ExecutionError

Base exception for runtime execution failures. Carries optional context: thread_name, step_index, step_type, and source_name.

Common causes:

  • Source read failure (Delta table not found, file path invalid)
  • Pipeline step failure (invalid Spark SQL expression, missing columns)
  • Write failure (target path not accessible, schema mismatch)
  • Merge mode missing write_config or match_keys
  • Target has no alias or path configured
  • Unsupported source type

Resolution:

  1. Check the error message for the thread name and step index
  2. Verify source tables/files exist and are accessible
  3. For merge mode, ensure write.match_keys is declared
  4. Test expressions in Spark SQL directly to isolate syntax issues

Example:

# Will fail — merge mode requires match_keys
write:
  mode: merge
  # Missing: match_keys

# Fixed
write:
  mode: merge
  match_keys: [customer_id]

Related: Add a Thread, Execution Modes


SparkError

Raised for Spark-specific execution failures. Reserved for future use — not currently raised. ExecutionError is used for all runtime failures.


StateError

Raised when watermark state cannot be read from or written to the configured store. Carries optional store_type context.

Common causes:

  • Target path contains backtick characters (unsupported by table properties store)
  • Failed to read watermark from table properties or metadata table
  • Failed to write watermark after successful execution
  • Metadata table path is not accessible

Resolution:

  1. Remove backticks from target paths
  2. Verify the target Delta table exists and has table properties enabled
  3. For metadata table store, verify the table_path is accessible
  4. Check Spark permissions for reading/writing table properties

Example:

# Will fail with StateError — backticks not allowed
target:
  path: "Tables/`my_table`"

# Fixed
target:
  path: Tables/my_table

Related: Idempotency, Execution Modes


HookError

Raised when a hook step (in pre_steps or post_steps) fails and its on_failure policy is set to abort. Carries hook-specific context: hook_name, hook_type, and phase.

Common causes:

  • A quality_gate check failed (e.g., source freshness exceeded max_age, row count outside bounds, table does not exist)
  • A sql_statement hook produced an error
  • An expression quality gate evaluated to false

Resolution:

  1. Check the error message for the hook name and phase (pre or post)
  2. For quality gate failures, verify the underlying data condition (source freshness, row counts, table existence)
  3. To make the hook non-blocking, set on_failure: warn instead of abort
  4. For SQL statement errors, test the SQL directly in Spark

Example:

pre_steps:
  # This will raise HookError if the source is older than 24h
  - type: quality_gate
    name: check_freshness
    check: source_freshness
    source: raw.orders
    max_age: "24h"
    on_failure: abort    # raise HookError on failure

  # Change to warn to log the issue without aborting
  - type: quality_gate
    name: check_freshness
    check: source_freshness
    source: raw.orders
    max_age: "24h"
    on_failure: warn     # log warning and continue

Related: YAML Schema: Weave


ExportError

Raised when an export write fails and its on_failure policy is set to abort. Carries export-specific context: export_name, export_type, and thread_name.

Common causes:

  • Export path is not writable or does not exist
  • Complex column types incompatible with the export format (e.g., arrays/maps in CSV)
  • Spark format writer error (invalid options, codec not available)

Resolution:

  1. Check the error message for the export name and format type
  2. Verify the export path is accessible and writable
  3. For format compatibility issues, simplify the schema or use a format that supports complex types (Delta, Parquet)
  4. To make the export non-blocking, set on_failure: warn instead of abort

Example:

exports:
  # This will raise ExportError if the write fails
  - name: compliance_copy
    type: delta
    alias: compliance.orders
    on_failure: abort    # raise ExportError on failure

  # Change to warn to log the issue without aborting
  - name: archive
    type: parquet
    path: /archive/orders/
    on_failure: warn     # log warning and continue

Related: Exports guide


WarpEnforcementError

Raised when warp contract enforcement finds violations and warp_enforcement is set to enforce. Carries a findings list with details about each violation.

Attributes:

  • findingslist[dict[str, str]] with keys: type (missing_column, type_mismatch, nullable_violation), column, expected, actual
  • thread_name — name of the thread that failed

Common causes:

  • Pipeline output is missing a column declared in the warp
  • A column's Spark type differs from the warp declaration
  • A non-nullable warp column contains null values

Resolution:

  1. Inspect findings to identify which columns failed
  2. Fix the pipeline to produce the expected columns and types
  3. Or update the warp to reflect the actual output schema
  4. Set warp_enforcement: warn to log findings without failing

Example:

target:
  alias: gold.dim_customer
  warp: dim_customer
  warp_enforcement: enforce  # raises WarpEnforcementError

Related: Warps guide


SchemaDriftError

Raised when schema drift is detected in strict mode with on_drift: error. Carries a drift_report with details about the extra columns found.

Attributes:

  • drift_reportDriftReport instance with extra_columns, action_taken, drift_mode, and baseline_source
  • thread_name — name of the thread that failed

Common causes:

  • Upstream source added columns that flow through all transforms to the target boundary
  • A new transform step introduces extra columns

Resolution:

  1. Inspect drift_report.extra_columns to see which columns are unexpected
  2. Add the columns to the warp if they are intentional
  3. Add a select step to filter unwanted columns
  4. Change on_drift: warn to drop extra columns with a warning instead of failing

Example:

target:
  alias: gold.dim_customer
  schema_drift: strict
  on_drift: error  # raises SchemaDriftError on extra columns

Related: Schema Drift guide


DataValidationError

Raised when a validation rule with fatal severity has failing rows. The thread aborts immediately — no data is written.

Common causes:

  • A fatal-severity validation rule has one or more failing rows
  • Source data violates an invariant that should never occur

Resolution:

  1. Inspect the source data for the failing condition
  2. Check the validation rule expression for correctness
  3. Consider downgrading severity to error (quarantine) if the rule should allow partial writes

Example:

validations:
  # This will abort the thread if ANY row has a null customer_id
  - name: customer_id_required
    rule: "customer_id IS NOT NULL"
    severity: fatal

  # Downgrade to error to quarantine bad rows instead of aborting
  - name: customer_id_required
    rule: "customer_id IS NOT NULL"
    severity: error  # bad rows go to quarantine table

Related: Add Validation Rules