DEV Community

umzzil nng
umzzil nng

Posted on • Originally published at oraerror.com

PostgreSQL 22027 Error: Causes and Solutions Complete Guide

PostgreSQL Error 22027: Trim Error — Causes, Fixes, and Prevention

PostgreSQL error code 22027 (trim_error) occurs when the TRIM(), BTRIM(), LTRIM(), or RTRIM() functions receive invalid or incompatible arguments during execution. This error commonly surfaces during data cleansing operations, ETL pipelines, or when user-supplied input is passed directly into SQL without proper validation. Understanding its root causes can save significant debugging time in production environments.


Top 3 Causes

1. Passing Invalid or Empty Trim Characters

Supplying an empty string or NULL as the trim character set leads to unexpected behavior or a direct 22027 error.

-- Problematic: empty string as trim character
SELECT TRIM('' FROM some_column) FROM some_table;

-- Fix: use COALESCE to handle NULLs and default BTRIM
SELECT BTRIM(COALESCE(some_column, '')) FROM some_table;

-- Fix: explicitly specify valid trim characters
SELECT BTRIM(some_column, ' \t\n\r') FROM some_table;

-- Safe wrapper function
CREATE OR REPLACE FUNCTION safe_trim(p_input TEXT)
RETURNS TEXT AS $$
BEGIN
    RETURN BTRIM(COALESCE(p_input, ''));
EXCEPTION
    WHEN SQLSTATE '22027' THEN
        RETURN p_input;
END;
$$ LANGUAGE plpgsql;
Enter fullscreen mode Exit fullscreen mode

2. Data Type Mismatch

Passing non-text types such as integer, boolean, or bytea directly to TRIM without explicit casting causes the function to fail during implicit type conversion.

-- Problematic: applying TRIM to a non-text column
SELECT TRIM(integer_column) FROM some_table;  -- ERROR 22027

-- Fix: explicit cast to TEXT before trimming
SELECT TRIM(integer_column::TEXT) FROM some_table;

-- Fix: handle bytea columns
SELECT TRIM(convert_from(bytea_column, 'UTF8')) FROM some_table;

-- Check column types before applying TRIM
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'your_table'
  AND table_schema = 'public';

-- Safe type-aware TRIM using CASE
SELECT
    CASE
        WHEN pg_typeof(col)::TEXT IN ('text', 'character varying', 'char')
            THEN TRIM(col::TEXT)
        ELSE col::TEXT
    END AS trimmed_col
FROM your_table;
Enter fullscreen mode Exit fullscreen mode

3. Unvalidated Dynamic SQL or ORM-Generated Queries

When application frameworks or ORMs dynamically construct SQL with unvalidated user inputs, TRIM arguments can be malformed or entirely missing, causing runtime 22027 errors.

-- Safe dynamic TRIM with input validation in PL/pgSQL
DO $$
DECLARE
    v_raw_input TEXT := '  user input value  ';
    v_clean     TEXT;
BEGIN
    IF v_raw_input IS NOT NULL AND LENGTH(v_raw_input) > 0 THEN
        v_clean := BTRIM(v_raw_input);
        RAISE NOTICE 'Cleaned value: [%]', v_clean;
    END IF;
END;
$$;

-- Bulk data cleansing with error safety
UPDATE users
SET username = BTRIM(username)
WHERE username IS NOT NULL
  AND username <> BTRIM(username);
Enter fullscreen mode Exit fullscreen mode

Quick Fix Solutions

If you encounter error 22027 in production, apply these immediate remedies:

-- 1. Wrap TRIM calls with exception handling
CREATE OR REPLACE FUNCTION robust_trim(p_value ANYELEMENT)
RETURNS TEXT AS $$
BEGIN
    RETURN BTRIM(p_value::TEXT);
EXCEPTION
    WHEN SQLSTATE '22027' THEN
        RAISE WARNING 'trim_error on value: %', p_value;
        RETURN p_value::TEXT;
END;
$$ LANGUAGE plpgsql;

-- 2. Validate and clean data before processing
SELECT robust_trim(col) FROM your_table WHERE col IS NOT NULL;

-- 3. Use regexp_replace as an alternative for edge cases
SELECT regexp_replace(some_column, '^\s+|\s+$', '', 'g')
FROM some_table;
Enter fullscreen mode Exit fullscreen mode

Prevention Tips

1. Always cast to TEXT before trimming
Never assume a column is already in text format. Add explicit ::TEXT casts in any query that uses TRIM, especially in dynamically generated SQL.

2. Use auto-trim triggers for critical tables

CREATE OR REPLACE FUNCTION trg_auto_trim() RETURNS TRIGGER AS $$
BEGIN
    NEW.name  := BTRIM(COALESCE(NEW.name, ''));
    NEW.email := BTRIM(LOWER(COALESCE(NEW.email, '')));
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER auto_trim_before_insert
BEFORE INSERT OR UPDATE ON users
FOR EACH ROW EXECUTE FUNCTION trg_auto_trim();
Enter fullscreen mode Exit fullscreen mode

These two habits alone will eliminate the vast majority of 22027 errors in production. Always validate inputs at both the application and database layers to build a robust defense against trim-related 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)