Skip to content

← Error codes catalogue · All exit codes

Exit code 2: Pre-flight failure

A pre-flight or schema-DDL check failed. Raised by PreflightError and CatalogError. Pre-data DDL failures happen before streaming; post-data DDL failures happen after rows are loaded — the run is marked failed (not succeeded) and is resumable once the fault is cleared.

Common causes

  • Target database contains user tables and on_existing_data: fail (default) in schema_mode: replicate.
  • schema_mode: assume_existing with on_existing_data: fail and an in-scope target table that already has rows (empty prebuilt tables are allowed; absence of identity/SERIAL columns does not change this).
  • schema_mode: assume_existing found a missing table or incompatible column type on the target (see schema.validation_failed in _privaci.audit_log).
  • passthrough_copy: require_binary and a passthrough table is not binary-COPY eligible (column order/type mismatch).
  • ner_mask is configured or auto-detected but SpaCy / en_core_web_sm is not available (pip install 'privaci[nlp]' or change the action).
  • Source or target unreachable, or insufficient privileges.
  • Missing CREATE SCHEMA privilege for _privaci.
  • A table referenced in config does not exist in the source.
  • Pre-data or post-data DDL failed on the target (permissions, missing dependencies, or invalid object definitions). Catalog identifiers in engine DDL are escaped via quote_pg_identifier before interpolation.
  • privaci resume found no resumable run, or the config, source database, or salt changed since the interrupted run. The error names which one drifted; a run is resumable while its status is in_progress, interrupted, or failed. Restore the original input or start a fresh run with privaci run --force-restart (requires on_existing_data: truncate or drop_create).
  • privaci resume in schema_mode: replicate when the incomplete run has no persisted source_schema_snapshot (schema cloning did not finish).
  • privaci run --force-restart with on_existing_data: fail (unsupported collision policy for force-restart).
  • passthrough_copy: require_binary together with null_orphan_fks on a table that references an excluded parent.
  • passthrough_copy: require_binary together with any column when: guard (conditional masking requires the batch/row path).

Remediation

# Inspect what pre-flight objected to:
privaci dry-run --config mask-rules.yaml

# If the target legitimately has data, choose an explicit policy:
#   on_existing_data: truncate   # wipe in-scope target tables first
#   on_existing_data: drop_create
# then abandon incomplete runs and start clean:
privaci run --force-restart --config mask-rules.yaml
# (append is rejected in the MVP — see docs/configuration.md)

Grant schema creation if needed:

GRANT CREATE ON DATABASE privaci_target TO privaci_role;