{"record":{"id":"872e58f165cff986","repo":"hibernate/hibernate-orm","slug":"cannot-parse-given-string-into-array-of-strings-o-872e58","errorCode":null,"errorMessage":"Cannot parse given string into array of strings. Outside of quote, but neither whitespace, comma, array end, nor null found.","messagePattern":"Cannot parse given string into array of strings\\. Outside of quote, but neither whitespace, comma, array end, nor null found\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/BasicCollectionJavaType.java","lineNumber":331,"sourceCode":"\t\t\t\t\t\tsb = null;\n\t\t\t\t\t}\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// i + 4, because there has to be a comma or closing brace after null\n\t\t\t\t\tif ( i + 4 < len\n\t\t\t\t\t\t\t&& charSequence.charAt( i ) == 'n'\n\t\t\t\t\t\t\t&& charSequence.charAt( i + 1 ) == 'u'\n\t\t\t\t\t\t\t&& charSequence.charAt( i + 2 ) == 'l'\n\t\t\t\t\t\t\t&& charSequence.charAt( i + 3 ) == 'l') {\n\t\t\t\t\t\tlist.add( null );\n\t\t\t\t\t\ti += 4;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif (i + 1 == len) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tthrow new IllegalArgumentException( \"Cannot parse given string into array of strings.\"\n\t\t\t\t\t\t\t+ \" Outside of quote, but neither whitespace, comma, array end, nor null found.\" );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( c == '\\\\' && i + 2 < len && (charSequence.charAt( i + 1 ) == '\\\\'\n\t\t\t\t\t|| charSequence.charAt( i + 1 ) == '\"') ) {\n\t\t\t\tc = charSequence.charAt( ++i );\n\t\t\t}\n\t\t\t// If there is ever a null-pointer here, the if-else logic before is incomplete\n\t\t\tsb.append( c );\n\t\t}\n\t\tfinal C result = semantics.instantiateRaw( list.size(), null );\n\t\tfor ( int i = 0; i < list.size(); i ++ ) {\n\t\t\tif ( list.get( i ) != null ) {\n\t\t\t\tresult.add( componentJavaType.fromString( list.get( i ) ) );\n\t\t\t}\n\t\t}\n\t\treturn result;\n\t}","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/BasicCollectionJavaType.java#L313-L349","documentation":"While scanning inside the braces, this parser accepts only quoted elements (\"...\"), the unquoted token null, whitespace and commas. Any other character found outside a quote — i.e. a bare unquoted element such as {red,green} — aborts with this IllegalArgumentException. Hibernate serializes every non-null string element in quotes, so an unquoted literal means the text came from some other producer (PostgreSQL's own output omits quotes when elements do not need them).","triggerScenarios":"Feeding '{one,two}' produced by native array_to_string(), psql output copied into fixtures, String.join(\",\", list) wrapped in braces by hand, or an upstream system emitting PostgreSQL ARRAY text where quoting is optional.","commonSituations":"Reporting/ETL tools normalizing array text; test fixtures pasted from psql; version of the literal format written by a different driver or library that quotes less aggressively.","solutions":["Quote every element when building literals: {\"one\",\"two\"}","Write values through Hibernate parameter binding so quoting is generated automatically","In native SQL, select the array column directly instead of array_to_string(...)","Emit nulls exactly as the unquoted four-letter token null"],"exampleFix":"// before\nString literal = \"{\" + String.join(\",\", List.of(\"one\", \"two\")) + \"}\"; // {one,two} -> throws\n\n// after\nString literal = list.stream()\n        .map(v -> v == null ? \"null\" : '\"' + v + '\"')\n        .collect(java.util.stream.Collectors.joining(\",\", \"{\", \"}\")); // {\"one\",\"two\"}","handlingStrategy":"validation","validationCode":"static String toHibernateStringArrayLiteral(List<String> values) {\n    return values.stream()\n        .map(v -> v == null ? \"null\"\n            : '\"' + v.replace(\"\\\\\", \"\\\\\\\\\").replace(\"\\\"\", \"\\\\\\\"\") + '\"')\n        .collect(java.util.stream.Collectors.joining(\",\", \"{\", \"}\"));\n} // always quote elements and escape backslash/quote before fromString()","typeGuard":null,"tryCatchPattern":"try {\n    Collection<String> c = basicCollectionJavaType.fromString(raw);\n} catch (IllegalArgumentException e) {\n    // unquoted literal from an external producer: parse leniently yourself\n    String inner = raw.substring(1, raw.length() - 1);\n    List<String> c = inner.isEmpty() ? List.of() : List.of(inner.split(\",\"));\n}","preventionTips":["Never assemble array literals with plain string concatenation","Remember psql and Hibernate do not quote literals identically","Route external array text through a quoting normalizer before handing it to Hibernate"],"tags":["hibernate","orm","array","parsing","quoting"],"backgroundTag":"array-string-parse-failed","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}