Advisory codes
Every advisory retrofit prints, by code. The register is the word a text line opens with and
the JSON level: warning or note. A braced name such as {table} is a value the printed
line fills in. A message that varies with a field shows each form on its own line, led by the
field’s value. Where the message is only such a value, its detail and hint lines follow it.
| Code | Class | Register | Message |
|---|---|---|---|
adopted-default-data-root | schema | warning | adopting the default data corpus root {path}, which already holds data files that no schema of this project owns, or that cannot be read as this project’s |
after-traffic-outcome | data-motion | note | {operator} {opid} meets rows that traffic wrote after it |
already-pinned | dml | note | {path} already anchors on {opid}; nothing was written |
apply-risk-add-not-null | apply-risk | warning | SET NOT NULL scans the table under an exclusive lock; on a populated table add a NOT VALID CHECK (col IS NOT NULL) in an earlier migration, then VALIDATE it and SET NOT NULL to avoid the long lock |
apply-risk-add-unique | apply-risk | warning | adding a UNIQUE constraint builds its index under an exclusive lock; on a populated table CREATE UNIQUE INDEX CONCURRENTLY first, then ADD CONSTRAINT … USING INDEX to avoid the long lock |
apply-risk-data-corpus | apply-risk | warning | {table}: some rows are not owned by this schema |
apply-risk-data-dropped | apply-risk | warning | {table}: {exclusion_cause}: some rows cannot be applied by this run |
apply-risk-data-exclusions | apply-risk | warning | history-bound, unroutable-purpose, superseded, table-dropped, table-filtered, undeclared, table-joined, table-split, table-merged, table-inlined, table-unjoined, reference-data: {table}: some rows are excluded from the captured datanot-selected: {count} dataset(s) not named ({table_count} table(s)); name them with –label, or run retrofit data list to see what is present |
apply-risk-data-exclusions-table | apply-risk | note | {table}: {exclusion_cause}: some rows did not reach the emitted band |
apply-risk-data-not-reversed | apply-risk | warning | down-not-reversed: {table}: {down_cause}: preserved DML is not reversed by –downno-fold-at-target: {table}: {down_cause}: the reference table has no fold at the target; its rows are kept |
apply-risk-import-summary | apply-risk | warning | the import carries {count} apply-risk advisories |
apply-risk-matview-refresh-cost | apply-risk | warning | {table}: refreshing this materialized view is not free |
apply-risk-rename-in-use | apply-risk | warning | table: renaming table “{name}” breaks readers still using the old namecolumn: renaming column “{name}” breaks readers still using the old name |
apply-risk-share-row-exclusive-lock | apply-risk | warning | validating foreign key on a populated table acquires SHARE ROW EXCLUSIVE lock for the scan, blocking writes |
apply-risk-validating-check | apply-risk | warning | validating CHECK constraint scans and locks the table; author it as NOT VALID (not_valid=true) then VALIDATE CONSTRAINT in a later migration (separate transaction) to avoid the long lock on a populated table |
apply-risk-validating-fk | apply-risk | warning | validating FOREIGN KEY scans and locks the table; author it as NOT VALID (not_valid=true) then VALIDATE CONSTRAINT in a later migration (separate transaction) to avoid the long lock on a populated table |
apply-risk-window-add-not-null | apply-risk | warning | schema {schema}: op {opid} sets NOT NULL on a column of {table} inside the migration window; the scan runs under an exclusive lock on a table that may hold rows |
apply-risk-window-unsealed | apply-risk | note | schema {schema}: no Seal, so the migration window begins at root and {table_count} tables in it were treated as newborn (empty); seal what production carries so the apply-risk gate can see it |
apply-risk-window-validating-check | apply-risk | warning | schema {schema}: op {opid} validates a CHECK constraint on {table} inside the migration window; the scan locks a table that may hold rows |
apply-risk-window-validating-fk | apply-risk | warning | schema {schema}: op {opid} validates a FOREIGN KEY on {table} inside the migration window; the scan locks a table that may hold rows |
atomicity-segment-boundary-crossed | atomicity | warning | {opid}: this migration spans more than one transaction |
atomicity-wrapper-suppressed | atomicity | warning | no BEGIN;/COMMIT; wrapper was emitted for this file |
boundary-requirement-commit-boundary | atomicity | warning | {operator} needs a transaction boundary that --envelope={target} leaves to the apply context |
boundary-requirement-non-transactional | atomicity | warning | {operator} needs a transaction boundary that --envelope={target} leaves to the apply context |
cascade-non-atomic-on-no-transaction | atomicity | note | ChangePrimaryKey appended with N={count} dependent FK rewrite(s); cascade must run inside one transaction to apply atomically (the default --envelope=own wrap satisfies this; --envelope=caller and --envelope=independent emit no wrapper, so the apply context must supply one) |
change-primary-key-non-atomic | atomicity | warning | cascade may apply partially: no BEGIN/COMMIT wrapper was emitted under --envelope={target} |
corpus-file-skipped | schema | warning | skipped malformed corpus file {path} |
corpus-foreign-records-present | apply-risk | warning | unregistered-owner: {count} record(s) under this corpus root are owned by other schemas: {owning_schemas}zero-owned: no record under this corpus root is owned by this schema; all {count} belong to: {owning_schemas} |
corpus-records-owned-by-other-schema | apply-risk | note | other-schema: {table}: {count} record(s) under this corpus root are owned by schema {schema}unregistered-schema: {table}: {count} record(s) under this corpus root are owned by no registered schema |
corpus-rollback-incomplete | schema | warning | rollback of {name} failed |
data-file-missing | data-motion | warning | the data record for {table} at {opid} ({path}), in the range this down reverts, is named by a witness, but no file carries it |
data-file-unaddressed | schema | warning | {path} is not an addressed data file and was not checked |
data-file-unfilled | schema | warning | unfilled data file {path}: it declares body=data but holds no filled records |
data-layer-below-floor | dml | note | {label} contributes to {table} at {contribution-anchor}, below the {lower-floor-kind} body={lower-floor-body} floor {lower-label} placed at {lower-floor-anchor} |
data-loss-on-apply | schema | warning | {reason} hint: matview-cache, null-key-rows, unreferenced-lookup-rows: capture the affected rows before applying, or re-shape the change to preserve themhint: drop-or-cast: capture the affected rows before applying, or re-shape the change to preserve them; under migrate --down, restore them from a backup taken before that op applied |
data-loss-on-apply-narrowing-cast | schema | warning | {table}: narrowing cast from {from_type} to {to_type} may lose data on apply |
data-loss-on-apply-render-chosen | schema | note | the reverse of {operator} {opid} loses the rows of {name} ({grade}) |
data-motion-cascade-scope | data-motion | note | {reason} |
data-motion-copy-post-fork-independence | data-motion | note | the copy and {table} are independent identities from this op forward; post-op edits to either table do not propagate to the other |
data-motion-declaration-inherited | data-motion | note | {table} is reference data because its source {target} is declared; if its rows are not reference data, withdraw it with retrofit schema ref-tables remove –schema {schema} {table} |
data-motion-deferred-split | data-motion | note | {table}: {count} split candidates deferred to a later batch |
data-motion-fresh-sequences | data-motion | note | {reason} |
data-motion-keyed-fold | data-motion | note | {operator} {opid} folds each inlined source’s columns and rows into {table} along their primary keys and drops the sources; the inlined columns take the survivor’s privileges and an inlined source’s grants end with it |
data-motion-partition-not-pg-declarative | data-motion | note | SplitTable is a row-axis split that moves rows into new tables and keeps its source; it does NOT emit PARTITION BY / PARTITION OF declarative-partitioning DDL |
data-motion-product-capture-owed | data-motion | note | {table} is reference data (declared source {target}), and the rows this op gives it exist only in migrated databases: capture {table} at HEAD (retrofit data capture <dump> –table {table}, then retrofit data witness) before op seal, which refuses reference-rows-uncaptured until then |
data-motion-replica-column | data-motion | warning | a snapshot proof writes {columns} into every row of {table}, so a logical-replication subscriber whose copy lacks the column stops applying at this transaction |
data-motion-source-consumed | data-motion | note | {count} source(s) end at this op; {table} stays and takes their rows; snapshot DDL stops emitting the sources from this opid forward |
data-motion-triggers | data-motion | note | {operator} {opid} writes rows the triggers listed here fire on; the render toggles no trigger |
data-only-single-statement-autocommit | atomicity | note | this --data-only band applies as individually autocommitted statements at {opid}: an abort mid-band leaves every completed phase committed |
data-qualified | dml | note | record seq={seq}: the renderer qualified {qualified_sites} |
data-replace-cascade | dml | warning | reaching: replacing {table} at {opid} reaches into {name}, which this slot does not replace ({reason})blocking: replacing {table} at {opid} may be blocked by rows in {name}, which this slot does not replace ({reason})reaching_ref: replacing reference table {table} at {opid} reaches into {name}, which this slot does not replace ({reason})blocking_ref: replacing reference table {table} at {opid} may be blocked by rows in {name}, which this slot does not replace ({reason})cross_slot: replacing {table} at {opid} acts on {name}, which is replaced in a different slot of this script ({reason})keyed_child: clearing {table} at {opid} meets rows in {name}, whose keyed staged block retains them through the clear ({reason})self: replacing {table} at {opid} acts on its own self-referencing foreign key ({reason}) |
data-replace-crossing | dml | warning | reference table {table} (floor at {opid}) is written as a keyed delta because this range crosses the removal of its declaration at {name}; rows the corpus never held are kept ({reason}) |
data-replace-prologue | dml | warning | {table} is replaced by its full observed state at {opid} ({reason}) |
data-replace-unordered | dml | note | the foreign-key graph could not be read at {opid} ({reason}), so the prologued tables ({values}) are emitted in the stated tie-break order |
data-replace-whole-reload | dml | warning | reloading {table} whole; {values} are not carried by the body and will be set to NULL |
data-witness-mismatch | data-motion | warning | the data record for {table} at {opid} ({path}), in the range this down reverts, no longer matches its witness |
data-witness-missing | data-motion | warning | the data record for {table} at {opid} ({path}), in the range this down reverts, has no witness in the covering seal’s range |
deferred-keys-bracketed | data-motion | note | the script sets the INITIALLY DEFERRED foreign keys of the ops that write rows immediate for each op and returns them to deferred |
deferred-keys-owed | data-motion | warning | the script writes rows under INITIALLY DEFERRED foreign keys and sets no constraint mode; under –envelope caller the enclosing transaction owes it |
deferred-keys-pending | data-motion | warning | data record seq={seq} leaves foreign-key checks on {schema}.{table} queued when op {operator} {opid} alters the table; that op fails 55006 (pending trigger events) |
dml-ahead-of-window | dml | warning | DML seq={opid} anchored on {name} is ahead of –to; omitted under –allow-unreached-dml |
dml-behind-window | dml | warning | root-boundary: DML seq={opid} purpose={purpose} anchored on the pre-genesis root boundary is behind –from; omittednamed-opid: DML seq={opid} purpose={purpose} anchored on {name} is behind –from; omitted |
dml-body-meta-command-admitted | dml | warning | {name} was emitted into the artifact under –allow-unscreened-dml; psql runs it client-side, outside retrofit’s transaction framing — a session command such as \connect ends the transaction open before it |
dml-body-partition-dependent | dml | warning | {name} cannot run inside a transaction block when its target relation is partitioned, and retrofit does not read the database catalog; if the target is partitioned, this window applies as one more segment than reported |
dml-chain-near-miss | dml | warning | {reason} hint: re-run with the prior label-set (or hand-edit the labels) if this was meant to supersede |
dml-dump-band-listed | dml | warning | {count} rows listed, not captured: {table} |
dml-op-show-matview-replace | dml | note | replacing materialized view {name} discards its stored rows |
dml-purpose-unclassified | dml | note | transition: {opid}: DML is classified as a transitionseed: {opid}: DML is classified as a seedcleanse: {opid}: DML is classified as a cleanseunclassified: {opid}: DML carries no purpose classificationref: {opid}: DML is classified as reference data |
dml-ref-table-flag-ignored | dml | note | {name} ignored: {table} is a declared reference table, so its record is purpose=ref |
dml-ref-table-no-match-universe | dml | note | schema {name} has no ops at HEAD, so no pattern can match yet |
dml-ref-table-policy-disagreement | dml | warning | {count} tables carry committed records their reference-data declaration would classify differently |
dml-ref-table-seed-dormant | dml | note | seed[{seed-labels}] holds {table} ({opid}); kept, never reclassified, and dormant while {table} is reference data |
dml-seed-band-opt-in-required | dml | warning | records in a purpose=seed file apply only{reason}; without it they are excluded and counted |
dml-unclassified-listed | dml | warning | {count} records unclassified: {table} |
drift-convert-recognition-gated | schema | note | partition-convert recognition inactive |
drift-extract-unrecognized | schema | warning | extract-shaped reshape not recognized as an ExtractTable |
drift-fk-facet-recapture | schema | warning | this recreate reconciles referential-action facets that differ between the oplog and the database; capturing them converges in one pass and does not recur |
drift-merge-shape-mismatch | schema | warning | merge sources differ on a compared field |
drift-move-column-candidate | schema | warning | a column dropped from one table and added to another was not recognized as a MoveColumn |
drift-skip-internal-defect | schema | warning | drift skip {skip_kind} on {name} in schema {schema} (line {line}) is a retrofit defect: valid PostgreSQL does not reach it with the pinned parser |
drift-skip-unclassified | schema | warning | unclassified drift skip {skip_kind} on {name} in schema {schema} (line {line}): {reason}; retrofit has no class for this skip, so it counts as a gap |
drift-split-unrecognized | schema | warning | same-shape table beside a surviving source was not recognized as a SplitTable |
drift-survivor-extract-unrecognized | schema | warning | column extract off surviving table {table} was not recognized as an ExtractTable |
enum-value-commit-boundary | type | note | the new value {name} on {target} is not usable until the adding transaction commits |
excluded-schema-referenced | schema | note | kept statements reference objects of the excluded schema {name}; each keeps the disposition a reference into an unmanaged schema has |
exclusion-applied | schema | note | ~ (excluded) {excluded_kind} {name} — {count} statement(s) — {reason} |
extract-rejoin-key-added | data-motion | note | the extract added rejoin keys that appear in no oplog text |
extract-rejoin-key-no-delete-action | data-motion | note | {operator} {opid} ties each child to {table} by a rejoin foreign key with no ON DELETE action, and its forward gives every {table} row a child row: a {table} row that has one can no longer be deleted |
extract-reverse-guard-non-atomic | atomicity | warning | a guard in this script is not atomic with the changes before it: no BEGIN;/COMMIT; wrapper was emitted under --envelope={envelope} |
extract-reverse-ordinal-divergence | data-motion | note | extract-reverse-ordinal-divergence |
extract-survivor-arm-selected | data-motion | note | source table {table} survives this extract in place |
from-dump-seal-run | dml | note | the dump matches a run of seals joined only by ops not observable in a schema-only dump |
gitattributes-missing | schema | warning | .gitattributes is missing the {config_path} line |
internal-advisory-write-failed | internal | warning | an advisory could not be written to its channel: {reason} |
internal-invalid-advisory | internal | warning | zero-def: advisory definition {original_code} is incomplete and cannot describe itselfundeclared-field: advisory definition {original_code} was supplied a field it does not declaremissing-field: advisory definition {original_code} is missing a value for a field it declarescontainer-mismatch: advisory definition {original_code} was supplied a value at the wrong container kindoff-token-discriminator: advisory definition {original_code} was supplied a discriminator value outside the closed token set it declares |
internal-reserved-type-violation | internal | warning | record type {type_name} is reserved for the advisory carrier and cannot be emitted through the generic {entry_point} writer |
join-key-demoted | schema | note | JoinTable carries primary key {name} ({element_id}) onto {table} as UNIQUE: {reason}; kept key {target} |
label-duplicated | dml | note | label {label} was named more than once; the repeat was dropped and the layering is unchanged |
label-unmatched | dml | warning | label {label} matched no data records; nothing was rendered for it |
legacy-origin-default | schema | note | a column’s stored default is a different spelling of the authored default |
migrate-segmented-non-atomic | atomicity | warning | {reason} hint: apply it with a runner that does NOT open its own transaction (plain psql -f); a runner wrapping the file in one transaction loses the boundary silently, at exit 0 |
move-column-down-refused | data-motion | note | migrate --down refuses a window holding this MoveColumn (migrate-move-column-needs-default): the moved column is NOT NULL with no DEFAULT |
owned-sequence-name-stale | schema | warning | a skipped statement leaves the owned sequence name {name} of {table}.{column} stale |
reference-chain-unfoldable | dml | warning | reference chain {table} does not fold offline: {reason} |
reference-declaration-unjudged | data-motion | note | op {opid} combined declared and undeclared tables into {schema}.{table} ({values} not declared), and no judgment records whether it is reference data; record one with retrofit schema ref-tables add –schema {schema} {table} or retrofit schema ref-tables remove –schema {schema} {table} before op seal, which refuses reference-declaration-unjudged until then |
reference-key-lost | dml | warning | reference table {table} lost {count} key(s) since its chain: {name} |
reference-restate-authored | dml | note | reference table {table}: a hand-written restate states the whole table and renders as a replace |
reference-table-emptied | dml | warning | reference table {table} was observed empty: the replace body=none removes every row |
rename-opaque-readers | schema | warning | table: renaming table “{name}” leaves function bodies retrofit cannot read; any may still use the old namecolumn: renaming column “{name}” leaves function bodies retrofit cannot read; any may still use the old name |
render-skip-element-not-rendered | render-skip | warning | view-body: {name} {element_id} omitted from snapshot: its body cannot be reconstructed without a live catalogelement-body: {name} {element_id} omitted from snapshot: its body references an element not live as of the cutunsupported-node: {name} {element_id} omitted from snapshot: an unsupported node in its body could not be rendered |
reverse-guard | atomicity | note | check: {operator} {opid} returns the check on {name} as a guardrule: {operator} {opid} returns the rule on {name} as a guardreference-edge: {operator} {opid} returns the reference edge on {name} as a guard |
reverse-irreversible | atomicity | note | paired: {name} is paired, not the element the target held: its rows left with the dropnot-null-not-restored: {name} comes back nullable: its NOT NULL is not restoredholder-child: {name} is rejoined as the holder child, not the element the target heldmatview-unpopulated: {name} is re-created WITH NO DATA, unpopulated until its REFRESHsynthesized-name: {name} is synthesized from a new ElementID, not the name the target’s cut rendersre-minted-name: {name} is re-minted by the key change, not the name the target’s cut rendersorder-not-restored: {name} keeps the column order the down leaves: its order is not restored |
reverse-noop | atomicity | note | left-validated: {name} is left validated: its validation contributes nothing to the downleft-not-valid: {name} is left NOT VALID by its declared policy: it contributes nothing to the down |
reverse-opaque | atomicity | note | RunRawScript {opid} reverses by its declared reverse_body, verbatim and unchecked |
reverse-slice | atomicity | note | the reverse is a slice to {opid}; {count} later operations are kept |
reverse-stop | atomicity | note | {operator} {opid} stops the reverse |
reverse-unrecorded | atomicity | note | this script is unrecorded: the oplog does not record the reverse it applies |
reverse-writes-before-rule | atomicity | note | {operator} {opid} relaxes the rule on {name} in {table} after earlier ghost ops wrote rows |
row-axis-report | data-motion | note | {operator} moves rows of {table}: {query} |
schema-body-finding | schema | warning | {name}: {opid} {diagnostic}: {reason} |
schema-context | schema | note | {schema} |
schema-deprecated-flag | schema | warning | --as={name} is deprecated for op show; use –framing={name} and the persistent –as=text|json for output mode |
schema-drift-observed | schema | warning | added: {target} exists in the database but not in the schemaremoved: {target} exists in the schema but not in the databasemodified: {target} differs between the schema and the databaserenamed: {target} appears renamed between the schema and the databaseunmodelled: {target} carries a facet the model does not representunresolved: {target} could not be resolved against the schemadeferred: {target} was deferred to a later drift pass |
schema-emission-sentinel | schema | warning | emission-path sentinel ({name}) |
schema-fork-unmerged | schema | warning | schema {schema}: {values} share prev={opid}; the oplog carries an unmerged fork |
schema-import-index-key-expression-unresolved | schema | warning | index {name} in schema {schema} was set aside: its key expression could not be resolved ({reason}) |
schema-import-skip-review | schema | note | some objects were set aside during import |
schema-import-unclassified-kind | schema | warning | an object kind reached the classifier with no matching arm |
schema-init-flag-ignored | schema | warning | {name} ignored |
schema-occupancy-undeterminable | schema | warning | {reason} |
schema-op-show-replay-finding | schema | warning | replay could not classify every op in this oplog |
schema-policy-references-unmodeled-role | schema | warning | policy {name} references role(s) {values} that retrofit does not track; verify they exist before apply |
schema-registry-empty | schema | note | no schemas are registered under {schema} |
schema-same-operator-as-tail | schema | warning | {operator} on lines {values} |
schema-stray-oplog | schema | warning | {path} |
split-table-down-refused | data-motion | note | migrate --down refuses a window holding this SplitTable: the split moved rows, and its reverse is a MergeTable you author |
stale-dml-reference | dml | warning | {reason} |
table-pattern-unmatched | dml | warning | –table pattern {name} matched no statement in the source |
type-creation-only | type | warning | type “{name}” is a serial pseudo-type usable only when creating a column; it is not a valid ALTER COLUMN … SET DATA TYPE target |
type-fk-partner-narrower | type | note | {target} stays {from_type} across foreign key {name} from a column cast to {to_type} |
type-unknown | type | warning | type “{name}” is not a recognized PostgreSQL built-in type |
type-varchar-without-length | type | warning | warning: type “{name}” without an explicit length is equivalent to textsuggestion: consider giving type “{name}” an explicit length |
validity-cannot-un-validate | schema | warning | {name}: the reverse of this change cannot re-validate {from_type} against {to_type} |
witness-digest-unsupported | data-motion | warning | the data record for {table} at {opid} ({path}), in the range this down reverts, has a witness whose digest algorithm is not supported |
witness-out-of-range | data-motion | warning | the data record for {table} at {opid} ({path}), in the range this down reverts, has a witness outside the seal range that covers it |