{"record":{"id":"41bf54c373d31f26","repo":"apache/iceberg","slug":"failed-to-write-spark-view-query-column-names","errorCode":null,"errorMessage":"Failed to write Spark view query column names","messagePattern":"Failed to write Spark view query column names","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"error","filePath":"spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/source/SparkViewQueryColumnNamesParser.java","lineNumber":37,"sourceCode":"package org.apache.iceberg.spark.source;\n\nimport com.fasterxml.jackson.databind.JsonNode;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport java.io.IOException;\nimport java.io.UncheckedIOException;\nimport org.apache.iceberg.relocated.com.google.common.base.Preconditions;\n\n/** Converts Spark view query column names to and from a property-safe JSON representation. */\nclass SparkViewQueryColumnNamesParser {\n  private static final ObjectMapper MAPPER = new ObjectMapper();\n\n  private SparkViewQueryColumnNamesParser() {}\n\n  static String toJson(String[] columnNames) {\n    try {\n      return MAPPER.writeValueAsString(columnNames);\n    } catch (IOException e) {\n      throw new UncheckedIOException(\"Failed to write Spark view query column names\", e);\n    }\n  }\n\n  static String[] fromJson(String json) {\n    try {\n      JsonNode node = MAPPER.readTree(json);\n      Preconditions.checkArgument(\n          node != null && node.isArray(),\n          \"Cannot parse Spark view query column names from non-array: %s\",\n          node);\n      String[] columnNames = new String[node.size()];\n      for (int index = 0; index < node.size(); index += 1) {\n        JsonNode columnName = node.get(index);\n        Preconditions.checkArgument(\n            columnName.isTextual(),\n            \"Cannot parse Spark view query column name from non-string: %s\",\n            columnName);\n        columnNames[index] = columnName.asText();","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/source/SparkViewQueryColumnNamesParser.java#L19-L55","documentation":"SparkViewQueryColumnNamesParser.toJson() serializes the view's query column names array to JSON. Any IOException from Jackson is rethrown as UncheckedIOException('Failed to write Spark view query column names', e), signaling serialization failed while persisting view metadata.","triggerScenarios":"MAPPER.writeValueAsString(columnNames) throwing during view creation/alter — practically caused by JsonMappingException from a bad ObjectMapper state or classpath issues, not by the String[] itself.","commonSituations":"Jackson version conflicts/shading on the classpath; corrupted ObjectMapper configuration; transient IO wrappers around metadata persistence.","solutions":["Inspect getCause() for the underlying IOException","Check for duplicate jackson-databind versions on the classpath","Retry view creation; if reproducible, gather versions and file an issue","Avoid replacing MAPPER or its configuration in custom forks"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if (columnNames == null) throw new IllegalArgumentException(\"Query column names are required for view metadata\");","typeGuard":null,"tryCatchPattern":"try { json = SparkViewQueryColumnNamesParser.toJson(columnNames); } catch (UncheckedIOException e) { log.error(\"Query column names serialization failed: {}\", e.getCause(), e); throw e; }","preventionTips":["Pass a plain String[] of column names","Keep Jackson dependencies consistent on the classpath","Check getCause() for the underlying Jackson exception"],"tags":["spark","iceberg","views","json","io"],"backgroundTag":"json-serialization-failed","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}