{"record":{"id":"dce5210452162020","repo":"prestodb/presto","slug":"invalid-cast-argument-dce521","errorCode":"INVALID_CAST_ARGUMENT","errorMessage":"Expected a json array, but got %s","messagePattern":"Expected a json array, but got (.+?)","errorType":"error_code","errorClass":"JsonCastException","httpStatus":null,"severity":"error","filePath":"presto-main-base/src/main/java/com/facebook/presto/operator/scalar/JsonToArrayCast.java","lineNumber":94,"sourceCode":"        BlockBuilderAppender elementAppender = BlockBuilderAppender.createBlockBuilderAppender(arrayType.getElementType());\n        MethodHandle methodHandle = METHOD_HANDLE.bindTo(arrayType).bindTo(elementAppender);\n        return new BuiltInScalarFunctionImplementation(\n                true,\n                ImmutableList.of(valueTypeArgumentProperty(RETURN_NULL_ON_NULL)),\n                methodHandle);\n    }\n\n    @UsedByGeneratedCode\n    public static Block toArray(ArrayType arrayType, BlockBuilderAppender elementAppender, SqlFunctionProperties properties, Slice json)\n    {\n        try (JsonParser jsonParser = createJsonParser(JSON_FACTORY, json)) {\n            jsonParser.nextToken();\n            if (jsonParser.getCurrentToken() == JsonToken.VALUE_NULL) {\n                return null;\n            }\n\n            if (jsonParser.getCurrentToken() != START_ARRAY) {\n                throw new JsonCastException(format(\"Expected a json array, but got %s\", jsonParser.getText()));\n            }\n            BlockBuilder blockBuilder = arrayType.getElementType().createBlockBuilder(null, 20);\n            while (jsonParser.nextToken() != JsonToken.END_ARRAY) {\n                elementAppender.append(jsonParser, blockBuilder, properties);\n            }\n            if (jsonParser.nextToken() != null) {\n                throw new JsonCastException(format(\"Unexpected trailing token: %s\", jsonParser.getText()));\n            }\n\n            return blockBuilder.build();\n        }\n        catch (PrestoException | JsonCastException e) {\n            throw new PrestoException(INVALID_CAST_ARGUMENT, format(\"Cannot cast to %s. %s%n%s\", arrayType, e.getMessage(), truncateIfNecessaryForErrorMessage(json)), e);\n        }\n        catch (Exception e) {\n            throw new PrestoException(INVALID_CAST_ARGUMENT, format(\"Cannot cast to %s.%n%s\", arrayType, truncateIfNecessaryForErrorMessage(json)), e);\n        }\n    }","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-main-base/src/main/java/com/facebook/presto/operator/scalar/JsonToArrayCast.java#L76-L112","documentation":"Thrown when casting a JSON value to an ARRAY type: the parser expects the top-level JSON to be an array ([...]), but encountered a different token (object, scalar, etc.). JsonToArrayCast.toArray reads the first token and, if it is neither null nor START_ARRAY, raises JsonCastException with the offending text, later wrapped as INVALID_CAST_ARGUMENT. A JSON value of a mismatched shape simply cannot become an array.","triggerScenarios":"Executing CAST(json_col AS ARRAY<T>) where json_col contains a JSON object ('{\"a\":1}'), a bare scalar ('42', '\"text\"', 'true'), or any non-array top-level value; toArray in JsonToArrayCast.java rejects the first non-START_ARRAY token.","commonSituations":"Casting a column that is usually an array but occasionally holds an object or scalar; querying JSON from external systems where the schema is not guaranteed; accidental passing of the whole JSON document instead of a subfield that is an array.","solutions":["Extract the correct array subfield first: CAST(json_extract(json_col, '$.items') AS ARRAY<...>) instead of casting the whole document.","Guard with json_typeof/JSONEquality checks, e.g. CASE WHEN json_typeof(json_col) = 'array' THEN CAST(...) END.","Fix upstream data to always emit arrays for this field.","Wrap in try_cast(...) to get NULL instead of a query failure for heterogeneous data."],"exampleFix":"// before\nSELECT CAST(payload AS ARRAY<BIGINT>) FROM t; -- payload = '{\"vals\":[1,2]}'\n\n// after\nSELECT CAST(json_extract(payload, '$.vals') AS ARRAY<BIGINT>) FROM t;","handlingStrategy":"validation","validationCode":"-- Validate top-level JSON type before casting\nSELECT CASE\n    WHEN json_typeof(payload) = 'array'\n    THEN CAST(payload AS ARRAY<BIGINT>)\n    ELSE NULL\nEND AS vals\nFROM t;","typeGuard":null,"tryCatchPattern":"// SQL: use try_cast for graceful degradation\nSELECT try_cast(payload AS ARRAY<BIGINT>) FROM t;","preventionTips":["Check json_typeof() before casting JSON columns of uncertain shape.","Extract the specific array subfield with json_extract rather than casting whole documents.","Enforce JSON schema contracts on upstream producers.","Prefer try_cast in ETL over hard casts for untrusted input."],"tags":["presto","json","cast","array","invalid-cast-argument"],"backgroundTag":"json-type-mismatch","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}