PostgreSQL error: column does not exist
ERROR: column "createdat" does not exist
LINE 1: SELECT createdAt FROM users;
^
HINT: Perhaps you meant to reference the column "users.createdAt".
PostgreSQL couldn't resolve a column name — and very often the HINT is already telling you why. Look at the sample: the query says createdAt, the error says "createdat", the hint offers "users.createdAt". That's the lowercase-folding rule at work.
What this error means
Two SQL rules produce nearly all of these errors:
- Unquoted identifiers fold to lowercase. A column created as
"createdAt"(quoted — ORMs and GUI tools love doing this) can only be referenced as"createdAt". UnquotedcreatedAtmeanscreatedat, a different name. - Double quotes delimit identifiers, single quotes delimit strings.
WHERE name = "alice"doesn't compare against the string 'alice' — it looks for a column calledalice, and fails with exactly this error.
Common causes
- Mixed-case column created with quotes, referenced without (or vice versa).
- Double quotes used for a string literal — the giveaway is the "missing column" being a data value.
- A SELECT alias used in
WHERE: aliases aren't visible there (the WHERE clause is evaluated before the select list).SELECT price * qty AS total ... WHERE total > 100fails. - Schema drift: the column genuinely doesn't exist in this environment because a migration hasn't run.
How to diagnose it
\d users -- nomi e case ESATTI delle colonne
Compare character by character, including case. If the query is generated by an ORM, log the actual SQL — the quoting the ORM emits is the whole story.
How to fix it
- Case problem → quote it exactly (
"createdAt") — or end the pain permanently:
Lowercase snake_case identifiers, never quoted, is the convention that avoids this class of bug entirely.ALTER TABLE users RENAME COLUMN "createdAt" TO created_at; - String literal → single quotes:
WHERE name = 'alice'. - Alias in WHERE → repeat the expression, or wrap the query:
SELECT * FROM (SELECT price * qty AS total ...) t WHERE total > 100.
🔍
Same rules, table edition: relation does not exist — search_path and quoted identifiers.
