PostgreSQL Error 42809: wrong object type
PostgreSQL error code 42809 (wrong_object_type) occurs when a SQL command is applied to a database object of an incompatible type. For example, running a table-only command like TRUNCATE or CLUSTER against a view, sequence, or index will immediately trigger this error. It is especially common during migrations, automation scripts, or ORM-generated queries where object type validation is skipped.
Top 3 Causes
1. Applying Table-Only Commands to a View
Views are virtual objects and do not store physical data. Commands like TRUNCATE, CLUSTER, or ALTER TABLE cannot be applied to views.
-- Create a view
CREATE VIEW v_active_users AS
SELECT * FROM users WHERE is_active = true;
-- Wrong: TRUNCATE on a view
TRUNCATE v_active_users;
-- ERROR: 42809: "v_active_users" is not a table
-- Fix: Use DELETE through the view (if updatable) or truncate the base table
DELETE FROM v_active_users;
-- OR
TRUNCATE users;
2. Using ALTER TABLE on a Sequence
Sequences are independent objects managed with ALTER SEQUENCE, not ALTER TABLE. Mixing up the two is a frequent mistake, especially in auto-generated scripts.
-- Wrong: Treating a sequence like a table
ALTER TABLE my_sequence ADD COLUMN notes TEXT;
-- ERROR: 42809: "my_sequence" is not a table
-- Fix: Use ALTER SEQUENCE for sequence-specific changes
ALTER SEQUENCE my_sequence RESTART WITH 500;
ALTER SEQUENCE my_sequence INCREMENT BY 2;
-- Verify the object type before running commands
SELECT relname, relkind
FROM pg_class
WHERE relname = 'my_sequence';
-- relkind 'S' = Sequence, 'r' = Table, 'v' = View
3. Issuing Table Commands Against a Composite Type or Foreign Table
Composite types created with CREATE TYPE and foreign tables defined via CREATE FOREIGN TABLE do not support many standard table operations.
-- Wrong: TRUNCATE on a composite type
CREATE TYPE address AS (street TEXT, city TEXT);
TRUNCATE address;
-- ERROR: 42809: "address" is not a table
-- Fix: Always verify the object type first
SELECT
relname,
CASE relkind
WHEN 'r' THEN 'TABLE'
WHEN 'v' THEN 'VIEW'
WHEN 'S' THEN 'SEQUENCE'
WHEN 'f' THEN 'FOREIGN TABLE'
WHEN 'c' THEN 'COMPOSITE TYPE'
WHEN 'i' THEN 'INDEX'
END AS object_type
FROM pg_class
WHERE relname = 'your_object_name';
Quick Fix Solutions
Before running any DDL or bulk operation, validate the target object type using pg_class:
-- Safe dynamic execution with type check (PL/pgSQL)
DO $$
DECLARE
v_kind CHAR;
BEGIN
SELECT relkind INTO v_kind
FROM pg_class
WHERE relname = 'target_object'
AND relnamespace = 'public'::regnamespace;
IF v_kind = 'r' THEN
EXECUTE 'TRUNCATE target_object';
RAISE NOTICE 'Truncated successfully.';
ELSE
RAISE WARNING 'Object is not a table. relkind = %', v_kind;
END IF;
END;
$$;
Prevention Tips
1. Always validate object types in scripts
Query pg_class or information_schema.tables before executing DDL commands in migration or automation scripts. Adding a type-check guard in PL/pgSQL procedures eliminates the risk entirely.
-- Quick object type audit for your schema
SELECT table_name, table_type
FROM information_schema.tables
WHERE table_schema = 'public'
ORDER BY table_type, table_name;
2. Enforce naming conventions
Adopt a strict naming convention across your team: prefix views with v_, sequences with seq_, and indexes with idx_. This makes it easy to identify object types at a glance and reduces the chance of applying the wrong command to the wrong object type.
Related Errors
| Error Code | Name | Notes |
|---|---|---|
42P01 |
undefined_table |
Triggered before 42809 if the object name doesn't exist at all |
0A000 |
feature_not_supported |
Similar context; appears with unsupported operations on foreign tables |
42601 |
syntax_error |
Often co-occurs with 42809 in malformed DDL scripts |
📖 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)