{"record":{"id":"ce86062347043c94","repo":"apache/beam","slug":"unsupported-beam-field-type-s-for-snowflake-column-s-beam","errorCode":null,"errorMessage":"Unsupported Beam field type %s for Snowflake column '%s'. Beam DECIMAL does not include Snowflake precision and scale information.","messagePattern":"Unsupported Beam field type (.+?) for Snowflake column '(.+?)'\\. Beam DECIMAL does not include Snowflake precision and scale information\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/io/snowflake/src/main/java/org/apache/beam/sdk/io/snowflake/SnowflakeSchemaTransformUtils.java","lineNumber":316,"sourceCode":"\n      case FLOAT:\n      case DOUBLE:\n        return SnowflakeDouble.of();\n\n      case STRING:\n        return SnowflakeVarchar.of();\n\n      case BOOLEAN:\n        return SnowflakeBoolean.of();\n\n      case BYTES:\n        return SnowflakeBinary.of();\n\n      case DATETIME:\n        return SnowflakeTimestamp.of();\n\n      case DECIMAL:\n        throw unsupportedFieldType(\n            field, \"Beam DECIMAL does not include Snowflake precision and scale information.\");\n\n      case ARRAY:\n      case ITERABLE:\n      case MAP:\n      case ROW:\n      case LOGICAL_TYPE:\n      default:\n        throw unsupportedFieldType(field, null);\n    }\n  }\n\n  public static IllegalArgumentException unsupportedFieldType(\n      Schema.Field field, @Nullable String details) {\n    String message =\n        String.format(\n            \"Unsupported Beam field type %s for Snowflake column '%s'.\",\n            field.getType().getTypeName(), field.getName());","sourceCodeStart":298,"sourceCodeEnd":334,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/io/snowflake/src/main/java/org/apache/beam/sdk/io/snowflake/SnowflakeSchemaTransformUtils.java#L298-L334","documentation":"Thrown by SnowflakeSchemaTransformUtils.toSnowflakeDataType when converting a Beam Schema field to a Snowflake column type and the field is a Beam DECIMAL. Snowflake's NUMBER type requires explicit precision and scale, but Beam's DECIMAL logical type in this path does not carry that metadata, so the connector refuses to guess and reports the limitation in the message details. This is a deliberate design boundary of the schema-mapping utility, not a data corruption issue.","triggerScenarios":"Calling toSnowflakeDataType (directly or via snowflakeType when generating a DDL statement for a staging table) with a Beam Schema.Field whose type is DECIMAL — typically produced when the inferred Beam schema of a PCollection contains NUMERIC/DECIMAL fields (e.g. from Avro, JDBC, or Calcite-inferred DECIMAL columns).","commonSituations":"Writing a Beam pipeline whose schema was inferred from sources that use DECIMAL/NUMERIC types (JDBC reads, Avro decimal logical types, BigQuery NUMERIC), then using SnowflakeIO schema transforms to write to Snowflake; Beam version upgrades that change type inference from DOUBLE to DECIMAL; hand-written schemas that use Schema.TypeName.DECIMAL assuming it maps to Snowflake NUMBER.","solutions":["Change the Beam field type from DECIMAL to DOUBLE (FLOAT) in the schema before writing to Snowflake, accepting floating-point representation.","Re-declare the field as STRING or INT64 in the Beam schema and handle precision/scale yourself.","Cast the value upstream: in the source query cast DECIMAL columns to DOUBLE/VARCHAR so Beam infers a supported type.","If exact precision/scale is required, bypass toSnowflakeDataType and create/annotate the Snowflake table (NUMBER(p,s)) yourself, then write with a schema using supported types."],"exampleFix":"// before\nschema = Schema.of(Schema.Field.of(\"amount\", Schema.FieldType.DECIMAL));\n\n// after\nschema = Schema.of(Schema.Field.of(\"amount\", Schema.FieldType.DOUBLE)); // or cast in source: CAST(amount AS DOUBLE)","handlingStrategy":"validation","validationCode":"// Check every field maps to a Snowflake type before attempting the write\nstatic List<String> unmappableFields(Schema schema) {\n  List<String> bad = new ArrayList<>();\n  for (Schema.Field f : schema.getFields()) {\n    switch (f.getType().getTypeName()) {\n      case BYTE: case INT16: case INT32: case INT64: case FLOAT: case DOUBLE:\n      case STRING: case BOOLEAN: case BYTES: case DATETIME:\n        break;\n      default: // includes DECIMAL, ARRAY, ITERABLE, MAP, ROW, LOGICAL_TYPE\n        bad.add(f.getName() + \":\" + f.getType().getTypeName());\n    }\n  }\n  return bad;\n}","typeGuard":"static boolean isSnowflakeMappable(Schema.Field field) {\n  Schema.TypeName t = field.getType().getTypeName();\n  return t == Schema.TypeName.BYTE || t == Schema.TypeName.INT16 || t == Schema.TypeName.INT32\n      || t == Schema.TypeName.INT64 || t == Schema.TypeName.FLOAT || t == Schema.TypeName.DOUBLE\n      || t == Schema.TypeName.STRING || t == Schema.TypeName.BOOLEAN\n      || t == Schema.TypeName.BYTES || t == Schema.TypeName.DATETIME;\n}","tryCatchPattern":"try {\n  schema.getFields().forEach(SnowflakeSchemaTransformUtils::toSnowflakeDataType);\n} catch (IllegalArgumentException e) {\n  throw new IllegalStateException(\"Schema not writable to Snowflake, fix DECIMAL fields first: \" + e.getMessage(), e);\n}","preventionTips":["Avoid Schema.FieldType.DECIMAL in schemas destined for this connector; prefer DOUBLE or INT64.","Cast NUMERIC/DECIMAL source columns to DOUBLE/VARCHAR in the source query so Beam infers a mappable type.","Run the unmappableFields check on the schema during pipeline construction (fail fast at graph build time, not at runtime).","Pin schema definitions explicitly instead of relying on inference from Avro/JDBC sources that default to DECIMAL."],"tags":["snowflake","apache-beam","schema-mapping","decimal"],"backgroundTag":"unsupported-dtype","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}