PostgreSQL Error 42704: undefined object
PostgreSQL error code 42704 (undefined_object) is raised when you attempt to reference, drop, or alter a database object — such as an index, constraint, custom type, operator, cast, or text search configuration — that does not exist in the current database or schema. Unlike 42P01 (undefined table) or 42703 (undefined column), this error specifically targets meta-level objects. It is most commonly encountered during migrations, rollback scripts, and automated deployments where schema states differ across environments.
Top 3 Causes
1. Dropping a Non-Existent Index or Constraint
This is the most frequent trigger. Running DROP INDEX or ALTER TABLE ... DROP CONSTRAINT without checking for existence — especially in multi-environment pipelines — causes this error immediately.
-- Causes ERROR 42704
DROP INDEX idx_orders_customer_id;
-- ERROR: index "idx_orders_customer_id" does not exist
-- Fix: Always use IF EXISTS
DROP INDEX IF EXISTS idx_orders_customer_id;
-- For constraints
ALTER TABLE orders DROP CONSTRAINT IF EXISTS fk_orders_customer;
-- Verify before dropping
SELECT indexname
FROM pg_indexes
WHERE schemaname = 'public'
AND tablename = 'orders'
AND indexname = 'idx_orders_customer_id';
2. Referencing an Undefined Custom Type or Operator
When a CREATE TABLE or CREATE FUNCTION statement references a custom type or operator that hasn't been created yet (or exists in a different schema), PostgreSQL throws 42704.
-- Causes ERROR 42704 if type doesn't exist
CREATE TABLE products (
id SERIAL PRIMARY KEY,
status product_status_type
);
-- ERROR: type "product_status_type" does not exist
-- Fix: Check existence first, then create
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_type
WHERE typname = 'product_status_type'
AND typnamespace = (
SELECT oid FROM pg_namespace WHERE nspname = 'public'
)
) THEN
CREATE TYPE public.product_status_type AS ENUM (
'active', 'inactive', 'discontinued'
);
END IF;
END;
$$;
-- Now safe to create the table
CREATE TABLE products (
id SERIAL PRIMARY KEY,
status public.product_status_type NOT NULL DEFAULT 'active'
);
3. Invalid Text Search Configuration Reference
Using to_tsvector(), to_tsquery(), or creating a GIN index with a text search configuration that does not exist on the target database will raise 42704.
-- Causes ERROR 42704
SELECT to_tsvector('korean', 'sample document text');
-- ERROR: text search configuration "korean" does not exist
-- Check available configurations
SELECT cfgname FROM pg_ts_config ORDER BY cfgname;
-- Use a built-in fallback or create a custom one
SELECT to_tsvector('simple', 'sample document text');
-- Safely create a custom config
CREATE TEXT SEARCH CONFIGURATION public.my_config (COPY = simple);
-- Create GIN index with valid config
CREATE INDEX idx_docs_fts
ON documents
USING GIN (to_tsvector('simple', title || ' ' || content));
Quick Fix Solutions
- Always append
IF EXISTSto everyDROPstatement in migration scripts. - Prefix object names with their schema (
public.my_type) to avoidsearch_pathresolution failures. - Query
pg_indexes,pg_type,pg_constraint, andpg_ts_configto verify object existence before executing DDL.
-- Useful diagnostic queries
-- Check indexes
SELECT * FROM pg_indexes WHERE tablename = 'your_table';
-- Check types
SELECT typname FROM pg_type WHERE typname = 'your_type';
-- Check constraints
SELECT conname FROM pg_constraint
WHERE conrelid = 'your_table'::regclass;
-- Fix search_path issues
SET search_path TO public, your_schema, pg_catalog;
Prevention Tips
Standardize
IF EXISTS/IF NOT EXISTSacross all DDL scripts. Enforce this as a team convention in code reviews and linting tools for SQL files. This single habit eliminates the majority of 42704 occurrences in CI/CD pipelines.Always qualify object names with their schema and validate via system catalogs before deployment. Build a pre-deployment health-check script that queries
pg_catalogviews, and run it against staging before applying changes to production. This catches schema drift early and prevents runtime failures.
📖 Want a more detailed guide?
Check out the full in-depth version (Korean) on oraerror.com — includes detailed analysis, additional SQL examples, and prevention tips.
Top comments (0)