Value-free error for the AshArcadic.Replicant sink boundary. Carries STRUCTURE
only — a reason atom, the resource module, and the sink op — never a source
row, a column value, or a tenant value.
The fail-closed halt paths raise this so nothing they refuse to write leaks
through the exception message (project_redaction_fail_path_exception_leak):
:tenant_required— a row carries no usable tenant (nil /false/ blank) for a resource declaring atenant_attribute, so the mirror write would land unscoped (AshArcadic.Replicant.Resolver.resolve_tenant!/3).:sensitive_plaintext— a non-skipped source column maps to a target attribute declaredarcade do sensitive ... end; the arriving Postgres value is plaintext and AshArcadic holds no key to encrypt it, so emitting it would write plaintext into a classified column (the F5 runtime guard inwritable_target/2/attrs_for_upsert/2).
The apply step (AshArcadic.Replicant.Apply) raises it for the fail-closed
effect-once paths:
:empty_identity— an upsert whose primary key resolves to an empty/partial identity (missing a PK value) would MERGE on an empty pattern and clobber unrelated vertices.:missing_primary_key— a delete whoseold_recordlacks a primary-key value (would buildid == nil, matching 0 rows and silently losing the delete).:truncate_halt— an upstream TRUNCATE arrived for a resource whoseon_truncateis:halt(the fail-closed default).:unsupported_op— a change carried an op the invariant map does not cover.:empty_index— the sink's resolver index is WHOLESALE empty (no mapped resources — empty/wrong domains), so every change would resolve toniland be silently dropped WHILE the checkpoint advances (permanent, invisible loss). The apply/snapshot paths fail closed on this BEFORE any write, so the checkpoint never advances and the transaction is re-delivered. Distinct from a NON-empty index with one unmapped table, which is a legitimate partial-publication skip.:sink_failed— a mirrored write failed at the data layer; the underlying exception is discarded value-free (its contents are never interpolated).
The pipeline start path raises it for the fail-closed start-mode:
:checkpoint_read_fault— reading the durable watermark at pipeline start faulted, so the checkpoint state is UNKNOWN and no start-mode (snapshot vs resume) can be chosen safely. Resuming forward-only on an actually-empty checkpoint would skip the required snapshot bootstrap and permanently omit every pre-slot row, so a read fault HALTS the start (a transient fault is an operator retry), never a silent forward-only (AshArcadic.Replicant.Pipeline).:missing_mirror_action— a mirror resource declares no primary create / destroy action, so the sink's apply path has no writable action to route the MERGE upsert / by-PK destroy through. A real mirror MUST be writable; this fails closed value-free at the apply seam rather than raising a rawprimary_action!error (AshArcadic.Replicant.Apply).
Summary
Functions
Create an Elixir.AshArcadic.Replicant.Error without raising it.
Types
@type reason() ::
:tenant_required
| :sensitive_plaintext
| :empty_identity
| :missing_primary_key
| :truncate_halt
| :unsupported_op
| :empty_index
| :sink_failed
| :checkpoint_read_fault
| :missing_mirror_action
Functions
@spec exception(opts :: Keyword.t()) :: %AshArcadic.Replicant.Error{ __exception__: true, bread_crumbs: term(), class: term(), op: term(), path: term(), reason: term(), resource: term(), splode: term(), stacktrace: term(), vars: term() }
Create an Elixir.AshArcadic.Replicant.Error without raising it.
Keys
- :reason
- :resource
- :op