{"record":{"id":"1ed2b00492593e41","repo":"apache/beam","slug":"two-accumulators-contain-different-initial-sequences-s-and-s","errorCode":null,"errorMessage":"Two accumulators contain different initial sequences: %s and %s","messagePattern":"Two accumulators contain different initial sequences: (.+?) and (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"sdks/java/extensions/ordered/src/main/java/org/apache/beam/sdk/extensions/ordered/combiner/SequenceRangeAccumulator.java","lineNumber":153,"sourceCode":"      throw new IllegalStateException(\"First entry is null when initial sequence is set.\");\n    }\n    Long start = firstEntry.getKey();\n    Long end = firstEntry.getValue().getLeft();\n    Instant latestTimestamp = firstEntry.getValue().getRight();\n    // Upper bound is inclusive, but the ContiguousSequenceRange's end is exclusive.\n    // The numeric overflow is prevented by dropping the value of Long.MAX.\n    return ContiguousSequenceRange.of(start, end + 1, latestTimestamp);\n  }\n\n  public int numberOfRanges() {\n    return data.size();\n  }\n\n  public void merge(SequenceRangeAccumulator another) {\n    if (this.initialSequence != null\n        && another.initialSequence != null\n        && !this.initialSequence.equals(another.initialSequence)) {\n      throw new IllegalStateException(\n          \"Two accumulators contain different initial sequences: \"\n              + this.initialSequence\n              + \" and \"\n              + another.initialSequence);\n    }\n\n    if (another.initialSequence != null) {\n      long newInitialSequence = another.initialSequence;\n      this.initialSequence = newInitialSequence;\n      Entry<Long, Pair<Long, Instant>> firstEntry = another.data.firstEntry();\n      if (firstEntry != null) {\n        Instant timestampOfTheInitialRange = firstEntry.getValue().getRight();\n        clearRangesBelowInitialSequence(newInitialSequence, timestampOfTheInitialRange);\n      }\n    }\n\n    another\n        .data","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/ordered/src/main/java/org/apache/beam/sdk/extensions/ordered/combiner/SequenceRangeAccumulator.java#L135-L171","documentation":"SequenceRangeAccumulator.merge() combines two accumulators during Beam combine. If both have non-null but different initialSequence values, merging would silently blend events from different streams, so it throws IllegalStateException. This protects the semantic that all events in one accumulator share the same starting sequence.","triggerScenarios":"mergeAccumulators combining accumulators built from elements with different initial sequences — caused by incorrect keying (elements of different keys funneled into one combine session), or a custom merge implementation bypassing key separation.","commonSituations":"Using a hot key / fanout that redistributes elements without preserving key identity; feeding the combiner events from multiple sources with unrelated sequence numbering; unit tests merging independent accumulators intentionally.","solutions":["Verify the input PCollection is keyed such that only events sharing one initial sequence reach the same accumulator.","Fix fanout/hot-key logic to maintain key separation before combine.","If legitimately merging independent streams, renumber sequences upstream so they share a consistent initial sequence.","Review custom mergeAccumulators overrides to ensure they only merge same-key accumulators."],"exampleFix":"// before\naccA.merge(accB); // initialSequence 1 vs 9 -> IllegalStateException\n// after\nif (accA.getInitialSequence().equals(accB.getInitialSequence())) {\n  accA.merge(accB);\n} else {\n  throw new IllegalArgumentException(\"cannot merge different streams\");\n}","handlingStrategy":"validation","validationCode":"if (a.getInitialSequence() != null && b.getInitialSequence() != null\n    && !a.getInitialSequence().equals(b.getInitialSequence())) {\n  throw new IllegalArgumentException(\"refusing to merge accumulators from different streams\");\n}","typeGuard":"static boolean mergeable(SequenceRangeAccumulator a, SequenceRangeAccumulator b) {\n  return a.getInitialSequence() == null || b.getInitialSequence() == null\n      || a.getInitialSequence().equals(b.getInitialSequence());\n}","tryCatchPattern":"try {\n  acc.mergeAccumulators(other);\n} catch (IllegalStateException e) {\n  if (e.getMessage().startsWith(\"Two accumulators contain different initial sequences\")) {\n    throw new IllegalStateException(\"check keying/fanout: different streams combined\", e);\n  }\n  throw e;\n}","preventionTips":["Maintain key identity through fanout and hot-key splitting","Only merge accumulators derived from the same keyed stream","Test combine merges with mixed-key inputs in unit tests"],"tags":["apache-beam","combiner","merge-conflict","invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}