Skip to main content
Every time supaschema runs — whether generating a migration, checking SQL, or verifying against a live database — it emits structured diagnostics. Each diagnostic carries a stable SUPA_* code, a severity level (error, warning, or info), a human-readable message, and an optional reference to the object or file involved. This page catalogs every code, explains what triggers it, and tells you exactly how to resolve it.
Run npx supaschema explain SUPA_CODE at any time to get an offline explanation of any diagnostic code — no internet required.

Severity levels

SeverityMeaning
errorsupaschema cannot safely continue. The operation is blocked until you resolve the issue.
warningsupaschema proceeded, but something needs your attention before you ship.
infoInformational only. No action required, but worth knowing.

Parse & Extract

These diagnostics fire during the initial SQL parsing and object-extraction phases, before any diffing or planning occurs.
CodeSeverityMeaningFix
SUPA_PARSE_ERRORerrorSQL failed to parse with the PostgreSQL parser.Check the SQL syntax in the failing file. The diagnostic message includes the file path and parser error text.
SUPA_PARSE_UNAVAILABLEerrorThe libpg-query native parser is not available in the current environment.Reinstall supaschema (npm install supaschema). If the problem persists on an unsupported platform, file an issue.
SUPA_EXTRACT_DUPLICATE_OBJECTerrorTwo source statements declare the same object identity (e.g., two CREATE TABLE public.users).Remove the duplicate CREATE statement. Each object must be declared exactly once across all schema source files.
SUPA_EXTRACT_UNSUPPORTEDwarningThe DDL statement is unsupported or ambiguous — supaschema cannot track it as a named schema object.Hand-author the statement in a separate, manually maintained migration file.
SUPA_EXTRACT_SIDE_EFFECT_UNSUPPORTEDwarningThe statement is a side-effect (INSERT, UPDATE, SET, etc.) rather than a schema object definition. Side-effects are not tracked in the schema model.Keep these statements in your reviewed, hand-authored migrations rather than in declarative schema files.
SUPA_EXTRACT_PARSER_REQUIREDerrorAST-level extraction was requested but the libpg-query parser is unavailable.Ensure the parser is installed (see SUPA_PARSE_UNAVAILABLE).
SUPA_OBJECT_PARSE_FAILEDwarningAn individual object’s SQL did not parse cleanly during extraction. The object may be partially recorded.Inspect the SQL for the referenced object and correct any syntax issues.

Catalog

These diagnostics fire when supaschema reads a live database catalog or compares against a saved snapshot.
CodeSeverityMeaningFix
SUPA_CATALOG_EXTRACT_FAILEDerrorLive catalog extraction from the target database failed.Verify that --database-url is correct, the database is reachable, and the connecting role has sufficient permissions (at minimum CONNECT and SELECT on system catalogs).
SUPA_CATALOG_SNAPSHOT_VERSIONwarningThe catalog snapshot was produced by a different version of supaschema. Object hashes may not compare correctly against the current version.Regenerate the snapshot with the current version of supaschema before diffing.

Planning

Planning diagnostics fire when supaschema computes the migration plan — the ordered list of operations needed to move from one schema state to another.
CodeSeverityMeaningFix
SUPA_PLAN_DESTRUCTIVE_HINT_REQUIREDerrorA destructive change (e.g., DROP TABLE) was detected, but no matching entry exists in hints.destructive. supaschema blocks destructive operations by default.Add the object’s fully-qualified key (e.g., public.users) to the hints.destructive array in your supaschema.config.json.
SUPA_PLAN_COLUMN_ALTER_HINT_REQUIREDerrorA column drop or type change was detected, but no matching entry exists in hints.destructive.Add the column’s key (e.g., public.users.email) to hints.destructive.
SUPA_PLAN_ADD_COLUMN_UNSAFEwarningA new column was added with an inline NOT NULL constraint, an identity definition, or a volatile default — any of which may rewrite the table or fail on non-empty tables.Review the generated SQL carefully. Consider adding the column as nullable first, back-filling data, then adding the constraint in a subsequent migration.
SUPA_PLAN_VIEW_REPLACE_INCOMPATIBLEerrorThe view’s column list changed in a way that makes CREATE OR REPLACE VIEW invalid. PostgreSQL requires the column list to be compatible for OR REPLACE.Add the view’s key to hints.destructive to allow a DROP VIEW + CREATE VIEW cycle, or restore column compatibility in your schema file.
SUPA_PLAN_VIEW_REPLACE_VERIFY_REQUIREDwarningThe view replacement was planned, but correctness verification has not been run.Run npx supaschema verify against a target database to confirm the replacement applies cleanly.
SUPA_PLAN_ROUTINE_RETURN_TYPE_CHANGEDerrorA function’s return type changed. CREATE OR REPLACE FUNCTION cannot change a return type.Add the function’s key to hints.destructive to allow a DROP FUNCTION + CREATE FUNCTION cycle.
SUPA_PLAN_RENAME_HINT_UNMATCHEDerrorA rename hint was provided but does not match exactly one source object and one target object.Check the hint key format — it must be "old_name->new_name" with fully-qualified identifiers.
SUPA_PLAN_RENAME_KIND_MISMATCHerrorA rename hint was matched but the source and target represent different object kinds (e.g., a table and a view).Correct the hint so that both sides reference objects of the same kind.
SUPA_PLAN_RENAME_SET_SCHEMA_UNSUPPORTEDerrorA rename hint would move an object from one schema to another. Cross-schema moves are not supported through rename hints.Remove the schema change from the rename hint. Use a separate ALTER ... SET SCHEMA in a hand-authored migration.
SUPA_PLAN_RENAME_UNSUPPORTEDerrorThe referenced object kind does not yet have a safe rename rendering in supaschema.Hand-author the rename in a separate migration file.
SUPA_PLAN_RENAME_VERIFY_REQUIREDwarningA rename operation was planned but has not been verified. Renames are sensitive to data continuity.Run npx supaschema verify to confirm the rename applies correctly.
SUPA_PLAN_CONCURRENT_INDEX_UNSUPPORTEDwarningA CREATE INDEX CONCURRENTLY statement was included in a transactional migration. CONCURRENTLY cannot run inside a transaction block.supaschema will split this into a separate concurrentSql file automatically when you use renderMigrationSplit. Apply that file outside a transaction.
SUPA_PLAN_DEPENDENCY_CYCLEerrorA circular dependency was detected between two or more schema objects. supaschema cannot safely order the operations.Break the cycle in your schema source by restructuring object dependencies.
SUPA_PLAN_EMPTY_WITH_DRIFTerrorThe plan produced zero operations, but the from-fingerprint and to-fingerprint differ — indicating silent drift masking rather than a clean no-op.Investigate why the planner produced no operations despite a fingerprint mismatch. This usually indicates a bug in a custom extraction pipeline; file an issue if you cannot trace the cause.

Diff & Lineage

These diagnostics protect the integrity of your migration history by ensuring each new migration correctly continues from the last applied state.
CodeSeverityMeaningFix
SUPA_DIFF_LINEAGE_BROKENerrorThe from state of the new plan does not match the to state of the newest pending migration in your migrations directory. The chain is broken.Regenerate the migration from the post-migration catalog state, or re-run supaschema diff after applying all pending migrations.
SUPA_DIFF_LINEAGE_DUPLICATEerrorA pending migration already covers exactly this from→to transition. Writing another would be redundant.Check whether you have already generated a migration for this set of changes. Delete the duplicate or apply the existing one.
SUPA_DIFF_OUTPUT_EXISTSerrorThe output file path already exists on disk. supaschema never silently overwrites migration files.Remove or rename the existing file, or choose a different output path with --output.

Check (Replay Safety)

The check phase performs static analysis on migration SQL to ensure it is idempotent, replay-safe, and free of common lock hazards. Errors indicate statements that will break on re-application or violate supaschema’s safety contract. Warnings indicate statements that may cause operational problems.

Idempotency & guard errors

CodeSeverityMeaningFix
SUPA_CHECK_CASCADEerrorA DROP ... CASCADE statement was found. Cascading drops can silently remove dependent objects.Replace with explicit drops of each dependent object in dependency order.
SUPA_CHECK_DROP_IF_EXISTSerrorA DROP statement is missing IF EXISTS. Without it, replaying the migration will fail if the object is already gone.Add IF EXISTS to every DROP statement.
SUPA_CHECK_CREATE_TABLE_GUARDerrorA CREATE TABLE statement is missing IF NOT EXISTS.Add IF NOT EXISTS.
SUPA_CHECK_CREATE_SCHEMA_GUARDerrorA CREATE SCHEMA statement is missing IF NOT EXISTS.Add IF NOT EXISTS.
SUPA_CHECK_CREATE_EXTENSION_GUARDerrorA CREATE EXTENSION statement is missing IF NOT EXISTS.Add IF NOT EXISTS.
SUPA_CHECK_CREATE_INDEX_GUARDerrorA CREATE INDEX statement is missing IF NOT EXISTS.Add IF NOT EXISTS.
SUPA_CHECK_CREATE_SEQUENCE_GUARDerrorA CREATE SEQUENCE statement is missing IF NOT EXISTS.Add IF NOT EXISTS.
SUPA_CHECK_CREATE_TYPE_GUARDerrorA CREATE TYPE or CREATE DOMAIN statement is missing a catalog existence guard.Wrap the statement with a DO $$ BEGIN ... EXCEPTION WHEN duplicate_object THEN NULL; END $$ guard, or let supaschema generate the migration for you.
SUPA_CHECK_CREATE_MATERIALIZED_VIEW_GUARDerrorA CREATE MATERIALIZED VIEW statement is missing IF NOT EXISTS.Add IF NOT EXISTS.
SUPA_CHECK_ADD_CONSTRAINT_GUARDerrorAn ADD CONSTRAINT statement is missing a catalog existence guard.Wrap with a catalog check so re-running the migration does not fail when the constraint already exists.
SUPA_CHECK_CREATE_VIEW_REPLACEerrorA CREATE VIEW statement is missing OR REPLACE. Without it, replaying the migration fails if the view already exists.Change to CREATE OR REPLACE VIEW.
SUPA_CHECK_CREATE_ROUTINE_REPLACEerrorA CREATE FUNCTION or CREATE PROCEDURE statement is missing OR REPLACE.Change to CREATE OR REPLACE FUNCTION / CREATE OR REPLACE PROCEDURE.
SUPA_CHECK_CREATE_TRIGGER_REPLACEMENTerrorA CREATE TRIGGER statement is neither CREATE OR REPLACE TRIGGER nor preceded by DROP TRIGGER IF EXISTS.Either use CREATE OR REPLACE TRIGGER (PostgreSQL 14+) or add DROP TRIGGER IF EXISTS ... ON ... CASCADE; immediately before the CREATE.
SUPA_CHECK_POLICY_REPLACEMENTerrorA CREATE POLICY statement is not preceded by DROP POLICY IF EXISTS. PostgreSQL has no OR REPLACE for policies.Add DROP POLICY IF EXISTS policy_name ON table_name; immediately before the CREATE POLICY.
SUPA_CHECK_INSERT_ON_CONFLICTerrorAn INSERT statement is missing ON CONFLICT. Without it, replaying the migration will raise a duplicate-key error.Add ON CONFLICT DO NOTHING or an appropriate ON CONFLICT (...) DO UPDATE clause.
SUPA_CHECK_SEARCH_PATHerrorA SET search_path statement was found inside the migration. Modifying search_path within a migration creates unpredictable behavior across environments.Remove the SET search_path statement. Use fully-qualified object names (schema.object) throughout the migration instead.
SUPA_CHECK_ENUM_VALUE_USE_SAME_TRANSACTIONerrorAn enum value added earlier in this migration file is used later in the same file. Transactional runners commit the ALTER TYPE … ADD VALUE and the subsequent statement together, but PostgreSQL does not make a new enum value visible until the transaction that added it commits.Move the statement that uses the new enum value into a separate migration file that runs after the one that adds it.

Lock hazard warnings

CodeSeverityMeaningFix
SUPA_CHECK_ALTER_COLUMN_TYPE_REWRITEwarningAn ALTER COLUMN TYPE statement may trigger a full table rewrite under an ACCESS EXCLUSIVE lock, blocking all reads and writes for the duration.Consider performing the type change in a zero-downtime pattern: add a new column, back-fill it, switch application code, then drop the old column.
SUPA_CHECK_SET_NOT_NULL_SCANwarningA SET NOT NULL constraint addition will scan the entire table to verify no nulls exist, holding a lock during the scan.On large tables, add a CHECK (col IS NOT NULL) NOT VALID constraint first, validate it in a separate transaction, then SET NOT NULL.
SUPA_CHECK_VOLATILE_DEFAULT_REWRITEwarningAn ADD COLUMN with a volatile default value (e.g., DEFAULT now(), DEFAULT gen_random_uuid()) will rewrite the entire table on PostgreSQL versions before 11.Ensure you are on PostgreSQL 11+ for safe volatile defaults, or add the column as nullable and back-fill separately.
SUPA_CHECK_NONTRANSACTIONAL_INDEXwarningA CREATE INDEX CONCURRENTLY statement is inside a transaction block. CONCURRENTLY cannot run inside a transaction and will fail.Apply CONCURRENTLY index statements outside a transaction block. supaschema splits these into a separate file automatically via renderMigrationSplit.
SUPA_CHECK_NONTRANSACTIONAL_REFRESHwarningA REFRESH MATERIALIZED VIEW CONCURRENTLY statement is inside a transaction block.Apply this statement outside a transaction block.
SUPA_CHECK_DML_REVIEWwarningAn UPDATE or DELETE statement was found. These are not inherently idempotent and require careful review to ensure re-running them is safe.Add idempotency guards (e.g., WHERE clauses that only match rows needing the change) and document the intent clearly.
SUPA_CHECK_SECURITY_DEFINER_SEARCH_PATHwarningA SECURITY DEFINER function does not explicitly set search_path. This is a security risk — an attacker who can create objects in a schema on the path can hijack the function.Add SET search_path = schema_name to the function definition.
SUPA_CHECK_DEPARSE_MISMATCHwarningA statement does not round-trip cleanly through the deparser — the deparsed form differs from the original. The statement will still be included, but the canonical form may differ.Review the flagged statement to confirm the semantic intent is preserved.
SUPA_CHECK_DEPARSE_UNSUPPORTEDwarningThe statement cannot be deparsed by the current version of supaschema. It will be included verbatim.No action required, but be aware the statement bypasses normalization.

Migrations Status

These diagnostics are reported by supaschema migrations status when comparing migration files on disk against the applied-history table in the database.
CodeSeverityMeaningFix
SUPA_MIGRATIONS_GHOST_VERSIONSerrorThe history table contains version records for migration files that no longer exist on disk.Reconcile the history table. If the files were intentionally deleted, remove the corresponding rows from the history table. If they were accidentally deleted, restore them.
SUPA_MIGRATIONS_OUT_OF_ORDERwarningOne or more pending migration files have version numbers older than the newest already-applied migration. Applying them could break ordering assumptions.Reorder the pending files to have version numbers after the newest applied migration, or remove them if they are no longer needed.
SUPA_MIGRATIONS_NO_TARGETinfoNo --database-url was provided. The status report is disk-only and does not reflect applied state.Pass --database-url to include live applied-state comparison.
SUPA_MIGRATIONS_HISTORY_TABLEerrorThe migrations history table is missing from the target database.Pass --history-table schema.table to specify the correct table name, or apply the initial supaschema bootstrap migration to create it.
SUPA_MIGRATIONS_TARGET_UNAVAILABLEerrorsupaschema could not connect to or read the target database.Check that --database-url is correct and the database is reachable from the current environment.

Verify

Verify diagnostics fire when supaschema applies a migration to a throwaway database and checks whether the resulting catalog matches the target schema model.
CodeSeverityMeaningFix
SUPA_VERIFY_FINGERPRINT_MISMATCHerrorThe catalog state after applying the migration does not match the target schema model. Some operations may be missing from the migration SQL.Inspect the migration SQL for gaps. Run npx supaschema diff after applying the migration against the verify database to surface the residual delta.
SUPA_VERIFY_RECONVERGENCEerrorResidual operations remain after the migration was applied — the schema has not fully converged.Run npx supaschema diff against the post-migration state to identify and add the missing statements.
SUPA_VERIFY_FAILEDerrorVerification could not complete due to an unexpected error.Check that --database-url is reachable and that the connecting role has CREATEDB permission. Review the full error output for details.
SUPA_VERIFY_ROLE_CAPABILITYerrorThe connecting role does not have CREATE DATABASE permission. supaschema needs this to create a throwaway verification database.Use a role with CREATEDB, or use supabase_admin if you are on Supabase.
SUPA_VERIFY_CLEANUP_FAILEDwarningThe temporary verification database could not be dropped after the verify run.Drop it manually: DROP DATABASE <name>. The database name is logged in the diagnostic message.

Other

CodeSeverityMeaningFix
SUPA_SYNC_RUNNER_FAILEDerrorThe migration runner (Supabase CLI) exited with a nonzero status code.Check the runner’s output for the underlying error. Ensure the Supabase CLI is installed and the migration SQL is valid.
SUPA_NORMALIZE_FIDELITYwarningThe deparsed form of an object’s SQL did not reparse identically to the original. The object is tracked but its normalized form may differ from what you wrote.Review the flagged object’s SQL. Minor whitespace or formatting differences are usually harmless; semantic differences require attention.
SUPA_NORMALIZE_UNSUPPORTEDwarningThe deparser cannot render this object type. The object will be tracked using its original SQL verbatim.No action required unless you are relying on normalized comparison across versions.
SUPA_SUPABASE_MANAGED_SCHEMAerrorA Supabase-managed schema (auth, storage, realtime, etc.) was specified as a declarative source owner. supaschema cannot manage these schemas.Remove the managed schema from your schemaPaths or source configuration. See the Support Matrix for the full block list.
SUPA_SUPABASE_VIEW_SECURITY_INVOKERwarningA view in an exposed schema (public, api, etc.) does not set security_invoker = true. On Supabase, views in exposed schemas run with the definer’s privileges by default, which may expose data unexpectedly.Add WITH (security_invoker = true) to the view definition.
SUPA_VALIDATOR_FAILEDerrorAn external SQL validator configured via validators in supaschema.config.json reported one or more diagnostics.Review the validator’s output. Fix the reported issues in the migration SQL, or reconfigure the validator rules if the finding is a false positive.
SUPA_VALIDATOR_UNAVAILABLEerrorA validator listed in supaschema.config.json is not installed or not on PATH.Install the missing validator, remove it from the config, or mark it as optional.
SUPA_VALIDATOR_UNKNOWNerrorThe validators config references a validator name that supaschema does not recognize.Check your supaschema.config.json for typos in the validators array and remove any unrecognized entries.
SUPA_SELFCHECK_HASH_MISMATCHerrorA catalog object hashes differently after its rendered SQL is re-extracted. Cross-lane diffs would report a false change.File an issue with the object SQL that triggers the mismatch. No user action is required in the meantime.
SUPA_SELFCHECK_MISSINGerrorA catalog object disappeared when its rendered SQL was re-extracted. This indicates an internal normalization issue.File an issue with the SQL for the affected object.
SUPA_SELFCHECK_UNEXPECTEDerrorRe-extraction of rendered SQL produced an object that the catalog model does not contain.File an issue with the SQL for the unexpected object.
SUPA_CORPUS_RECONVERGENCEerrorThe corpus oracle did not converge: residual operations remain after the rendered reconciliation was applied to the dirty corpus database, or the second apply changed the catalog.Review the corpus configuration and the objects named in the diagnostic. This usually indicates a rendering gap — file an issue if you cannot trace the cause.