{"record":{"id":"a40fade0d1ba2980","repo":"apache/iceberg","slug":"cannot-parse-default-as-a-s-value-s","errorCode":null,"errorMessage":"Cannot parse default as a %s value: %s","messagePattern":"Cannot parse default as a (.+?) value: (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/SingleValueParser.java","lineNumber":94,"sourceCode":"            \"Cannot parse default as a %s value: %s\",\n            type,\n            defaultValue);\n        return defaultValue.floatValue();\n      case DOUBLE:\n        Preconditions.checkArgument(\n            defaultValue.isFloatingPointNumber(),\n            \"Cannot parse default as a %s value: %s\",\n            type,\n            defaultValue);\n        return defaultValue.doubleValue();\n      case DECIMAL:\n        Preconditions.checkArgument(\n            defaultValue.isTextual(), \"Cannot parse default as a %s value: %s\", type, defaultValue);\n        BigDecimal retDecimal;\n        try {\n          retDecimal = new BigDecimal(defaultValue.textValue());\n        } catch (NumberFormatException e) {\n          throw new IllegalArgumentException(\n              String.format(\"Cannot parse default as a %s value: %s\", type, defaultValue), e);\n        }\n        Preconditions.checkArgument(\n            retDecimal.scale() == ((Types.DecimalType) type).scale(),\n            \"Cannot parse default as a %s value: %s, the scale doesn't match\",\n            type,\n            defaultValue);\n        return retDecimal;\n      case STRING:\n        Preconditions.checkArgument(\n            defaultValue.isTextual(), \"Cannot parse default as a %s value: %s\", type, defaultValue);\n        return defaultValue.textValue();\n      case UUID:\n        Preconditions.checkArgument(\n            defaultValue.isTextual() && defaultValue.textValue().length() == 36,\n            \"Cannot parse default as a %s value: %s\",\n            type,\n            defaultValue);","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/SingleValueParser.java#L76-L112","documentation":"SingleValueParser.fromJson parses a JSON default value for a column type when reading schema JSON. For DecimalType the JSON node must be a textual decimal string, and the parsed value's scale must exactly equal the type's declared scale. This error is thrown when the default value is not a text node or cannot be parsed as a BigDecimal (or, in the adjacent check, has a mismatched scale), i.e. the schema JSON does not conform to the Iceberg spec for decimal defaults.","triggerScenarios":"Calling SingleValueParser.fromJson(jsonNode, Types.DecimalType.of(precision, scale)) with a JSON node that is non-textual (numeric/boolean/object), contains a non-decimal string (e.g. \"1.2.3\", \"abc\", \"1e999\" overflowing), or a decimal string whose scale differs from the type's scale (e.g. \"1.50\" for scale(1)).","commonSituations":"Hand-written or third-party-generated schema JSON where decimal defaults were written as JSON numbers instead of strings, or with the wrong number of fractional digits; schema files produced by other tools that don't follow Iceberg's kebab-case JSON conventions; typos in default values in table metadata.","solutions":["Fix the schema JSON so the decimal default is a quoted string matching the declared scale, e.g. \"default\": \"12.3\" for DecimalType.of(4, 1).","Remove the invalid default value from the schema JSON and add it programmatically via UpdateSchema (setDefault) so Iceberg validates and formats it correctly.","Validate the JSON before parsing: check defaultValue.isTextual() and new BigDecimal(text).scale() == expectedScale, and normalize (setScale/stripTrailingZeros) as needed."],"exampleFix":"// before (schema JSON)\n{\"type\": \"decimal(4, 1)\", \"default\": 12.3}\n\n// after\n{\"type\": \"decimal(4, 1)\", \"default\": \"12.3\"}","handlingStrategy":"validation","validationCode":"if (node == null || !node.isTextual()) {\n  throw new IllegalArgumentException(\"Decimal default must be a JSON string\");\n}\njava.math.BigDecimal d = new java.math.BigDecimal(node.textValue());\nif (d.scale() != decimalType.scale()) {\n  throw new IllegalArgumentException(\"Decimal default scale \" + d.scale() + \" != \" + decimalType.scale());\n}","typeGuard":"null","tryCatchPattern":"try {\n  Object v = SingleValueParser.fromJson(node, Types.DecimalType.of(precision, scale));\n} catch (IllegalArgumentException | NumberFormatException e) {\n  throw new IllegalArgumentException(\"Invalid decimal default '\" + node.textValue()\n      + \"' for decimal(\" + precision + \",\" + scale + \")\", e);\n}","preventionTips":["Always emit decimal default values as quoted JSON strings, never JSON numbers.","Ensure the literal's fractional digits exactly match the declared scale (\"12.30\" for scale 2).","Set defaults through UpdateSchema.setDefault so Iceberg validates and serializes them correctly.","Pre-validate hand-written or third-party schema JSON with SchemaParser before use."],"tags":["java","json","decimal","schema","parsing"],"backgroundTag":"invalid-argument-format","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}