prestodb/presto · error · PrestoException

INVALID_CAST_ARGUMENT

INVALID_CAST_ARGUMENT

Error message

Cannot cast '%s' to %s

What it means

CAST(json AS VARCHAR) in JsonOperators.castToVarchar rethrows any IOException or JsonCastException as INVALID_CAST_ARGUMENT, echoing the raw JSON bytes and the target type VARCHAR. It fires when the json value cannot be parsed as a single JSON value or a trailing token exists after it.

Source

Thrown at presto-main-base/src/main/java/com/facebook/presto/operator/scalar/JsonOperators.java:94

    private JsonOperators()
    {
    }

    @ScalarOperator(CAST)
    @SqlNullable
    @LiteralParameters("x")
    @SqlType("varchar(x)")
    public static Slice castToVarchar(@SqlType(JSON) Slice json)
    {
        try (JsonParser parser = createJsonParser(JSON_FACTORY, json)) {
            parser.nextToken();
            Slice result = currentTokenAsVarchar(parser);
            checkCondition(parser.nextToken() == null, INVALID_CAST_ARGUMENT, "Cannot cast input json to VARCHAR"); // check no trailing token
            return result;
        }
        catch (IOException | JsonCastException e) {
            throw new PrestoException(INVALID_CAST_ARGUMENT, format("Cannot cast '%s' to %s", json.toStringUtf8(), VARCHAR), e);
        }
    }

    @ScalarOperator(CAST)
    @SqlNullable
    @SqlType(BIGINT)
    public static Long castToBigint(@SqlType(JSON) Slice json)
    {
        try (JsonParser parser = createJsonParser(JSON_FACTORY, json)) {
            parser.nextToken();
            Long result = currentTokenAsBigint(parser);
            checkCondition(parser.nextToken() == null, INVALID_CAST_ARGUMENT, "Cannot cast input json to BIGINT"); // check no trailing token
            return result;
        }
        catch (IOException | JsonCastException e) {
            throw new PrestoException(INVALID_CAST_ARGUMENT, format("Cannot cast '%s' to %s", json.toStringUtf8(), BIGINT), e);
        }
    }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Fix the producer so the JSON column contains exactly one valid document.
  2. Re-parse the raw source text with try(json_parse(...)) to sanitize, then cast.
  3. Use try(CAST(j AS VARCHAR)) to get NULL for corrupt rows instead of failing the query.

Example fix

-- before
SELECT CAST(raw_json AS VARCHAR) FROM t; -- raw_json malformed
-- after
SELECT CAST(try(json_parse(raw_text)) AS VARCHAR) FROM t; -- sanitized, NULL on invalid
Defensive patterns

Strategy: validation

Validate before calling

SELECT try(CAST(j AS VARCHAR)) FROM t; -- NULL instead of query failure on corrupt json values

Try / catch

try { String s = (String) session.execute("SELECT CAST(j AS VARCHAR)"); } catch (PrestoException e) { if (e.getErrorCode().getName().equals("INVALID_CAST_ARGUMENT")) return null; throw e; }

Prevention

When it happens

Trigger: Casting a corrupted/invalid json-typed value to VARCHAR, e.g. CAST(malformed AS VARCHAR) or json values containing trailing garbage produced by a faulty pipeline; note the earlier checkCondition already rejects trailing tokens and this catch converts parser failures.

Common situations: Json values produced by non-conforming producers (multiple concatenated documents, truncated writes); round-tripping through systems that mangle JSON; debugging columns typed JSON that actually hold raw text.

Related errors


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/27ba607ff2a10755. Report an issue: GitHub.