Errore PostgreSQL: value too long for type character varying
ERROR: value too long for type character varying(50)
Una stringa ha superato il limite di lunghezza dichiarato della sua colonna, e PostgreSQL ha rifiutato la scrittura invece di troncarla silenziosamente. Fastidiosamente, il messaggio indica il tipo ma non la colonna — trovare quale colonna è il primo passo.
Cosa significa questo errore
Due fatti specifici di PostgreSQL inquadrano la soluzione:
- Non c'è alcun beneficio di performance in
varchar(n)rispetto atextin PostgreSQL — sono memorizzati in modo identico. Il limite è puramente un vincolo, quindi dovrebbe esistere solo dove il business ne ha davvero uno. - Allargare un varchar non riscrive la tabella — aumentare il limite è una modifica rapida al solo catalogo.
Cause comuni
- Dati reali cresciuti oltre un limite arbitrario — il
varchar(255)da cargo cult che incontra un URL, uno user agent o un indirizzo lungo. - Concatenazioni o campi denormalizzati cresciuti oltre la stima originale.
- Import con mapping delle colonne errato che mette valori lunghi in campi corti.
Come diagnosticarlo
-- Quali colonne varchar(50) ha la tabella sospetta:
SELECT column_name, character_maximum_length
FROM information_schema.columns
WHERE table_name = 'users' AND character_maximum_length IS NOT NULL;
Poi confronta con il payload che è fallito. Se lo statement è loggato, i valori sono proprio lì.
Come risolverlo
- Allargalo (veloce, solo catalogo):
ALTER TABLE users ALTER COLUMN name TYPE varchar(200); - Oppure rimuovi del tutto il limite arbitrario —
text, con un vincolo CHECK se un qualche limite conta davvero:
Un CHECK è più facile da modificare in seguito rispetto a un tipo.ALTER TABLE users ALTER COLUMN name TYPE text; ALTER TABLE users ADD CONSTRAINT name_reasonable CHECK (length(name) <= 1000); - Tronca lato client solo se il troncamento è davvero accettabile (
left(value, 50)) — quella è una decisione di prodotto, non un default del database, ed è esattamente il motivo per cui PostgreSQL si rifiuta di prenderla per te.
