{"record":{"id":"67746827bb5dc3d4","repo":"apache/beam","slug":"micros-instant-logical-type-encountered-a-java-instant-with","errorCode":null,"errorMessage":"micros_instant logical type encountered a Java Instant with greater than microsecond precision.","messagePattern":"micros_instant logical type encountered a Java Instant with greater than microsecond precision\\.","errorType":"exception","errorClass":"AssertionError","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/logicaltypes/MicrosInstant.java","lineNumber":56,"sourceCode":" * NanosInstant}.\n */\npublic class MicrosInstant implements Schema.LogicalType<Instant, Row> {\n  public static final String IDENTIFIER =\n      SchemaApi.LogicalTypes.Enum.MICROS_INSTANT\n          .getValueDescriptor()\n          .getOptions()\n          .getExtension(RunnerApi.beamUrn);\n  // TODO(https://github.com/apache/beam/issues/20540): This should be a constant\n  private final Schema schema;\n\n  public MicrosInstant() {\n    this.schema = Schema.builder().addInt64Field(\"seconds\").addInt32Field(\"micros\").build();\n  }\n\n  @Override\n  public Row toBaseType(Instant input) {\n    if (input.getNano() % 1000 != 0) {\n      throw new AssertionError(\n          \"micros_instant logical type encountered a Java \"\n              + \"Instant with greater than microsecond precision.\");\n    }\n    return Row.withSchema(schema).addValues(input.getEpochSecond(), input.getNano() / 1000).build();\n  }\n\n  @Override\n  public Instant toInputType(Row row) {\n    return Instant.ofEpochSecond(\n        checkArgumentNotNull(\n            row.getInt64(0), \"While trying to convert to Instant: Row missing seconds field\"),\n        checkArgumentNotNull(\n                row.getInt32(1), \"While trying to convert to Instant: Row missing micros field\")\n            * 1000);\n  }\n\n  @Override\n  public String getIdentifier() {","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/schemas/logicaltypes/MicrosInstant.java#L38-L74","documentation":"The micros_instant logical type represents instants with only microsecond precision. toBaseType throws an AssertionError if the java.time.Instant has sub-microsecond nanos (nano % 1000 != 0), since precision would be lost.","triggerScenarios":"Converting an Instant created with nanosecond precision (e.g. Instant.now() on JVMs reporting finer clocks, or truncatedFrom with NANOS) through a schema using MicrosInstant.","commonSituations":"Passing Instant.now() values directly into rows on JDK 9+ where the clock can have nanosecond resolution.","solutions":["Truncate the Instant to microseconds before conversion: input.truncatedTo(ChronoUnit.MICROS).","Normalize at the source (round/truncate timestamps when produced).","If nanosecond precision is required, use a logical type that supports nanos instead of micros_instant."],"exampleFix":"// before\nRow r = Row.withSchema(schema).addValues(Instant.now(), ...).build();\n\n// after\nInstant t = Instant.now().truncatedTo(ChronoUnit.MICROS);\nRow r = Row.withSchema(schema).addValues(t, ...).build();","handlingStrategy":"validation","validationCode":"// Java: truncate instants to microsecond precision before use\nInstant safe = input.truncatedTo(ChronoUnit.MICROS);","typeGuard":"// Java\npublic static boolean isMicrosPrecise(Instant t) { return t.getNano() % 1000 == 0; }","tryCatchPattern":null,"preventionTips":["Truncate all Instant.now() and external timestamps to ChronoUnit.MICROS.","Never feed nanosecond-precision sources into micros_instant columns."],"tags":["java","timestamp","precision","logical-type"],"backgroundTag":"value-out-of-range","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}