Bug
The writer's edition guard filters out-of-edition encodings only among the encoders VortexWriter itself lists (encodings + cascadeCodecs). VortexWriter.editionExcluded builds its set from those two lists alone.
Some encoders keep a private candidate list that never goes through those lists. SparseEncodingEncoder.INDEX_CASCADE_CANDIDATES, used to compress a sparse validity bitmap's patch indices, offers fastlanes.delta, which is an unstable-family encoding. Its id never lands in editionExcluded, so CascadingCompressor's per-candidate ctx.excluded() check lets it compete under the default core edition.
Impact
While plain (terminal) delta always lost that competition, the bug stayed latent. Once delta cascades its children (#410 / #439), it wins on regular patch indices, and a default-edition write fails the backstop guard:
VortexException: fastlanes.delta: outside the configured edition(s) [core2026.08.0];
it joins unstable2025.05.0 — enable that edition via WriteOptions.withEdition(...)
Reproduce
A nullable Utf8 column of 50k rows (8 categories, a null every 10th row), written with WriteOptions.cascading(3).withGlobalDict(false) and default editions. The periodic nulls make the validity sparse with perfectly regular patch indices. This was hit by FileSizeComparisonIntegrationTest (nullableLowCardinalityUtf8_javaVsJni, nullableLowCardinalityUtf8_multiChunk_globalDict_javaVsJni, globalDict_nullableMultiChunkUtf8_smallerThanPerChunkDict).
Fix
editionExcluded covers every EncodingId.WellKnown id outside the enabled editions, plus custom encoders the writer holds, so private candidate lists obey the same policy. This is safe by construction: anything newly excluded would have failed the backstop guard anyway. The regression test WriterEditionGuardTest#cascading_defaultEditions_privateCandidateListsHonorTheEdition fails without the fix. Fixed in #439.
Bug
The writer's edition guard filters out-of-edition encodings only among the encoders
VortexWriteritself lists (encodings+cascadeCodecs).VortexWriter.editionExcludedbuilds its set from those two lists alone.Some encoders keep a private candidate list that never goes through those lists.
SparseEncodingEncoder.INDEX_CASCADE_CANDIDATES, used to compress a sparse validity bitmap's patch indices, offersfastlanes.delta, which is an unstable-family encoding. Its id never lands ineditionExcluded, soCascadingCompressor's per-candidatectx.excluded()check lets it compete under the defaultcoreedition.Impact
While plain (terminal) delta always lost that competition, the bug stayed latent. Once delta cascades its children (#410 / #439), it wins on regular patch indices, and a default-edition write fails the backstop guard:
Reproduce
A nullable Utf8 column of 50k rows (8 categories, a null every 10th row), written with
WriteOptions.cascading(3).withGlobalDict(false)and default editions. The periodic nulls make the validity sparse with perfectly regular patch indices. This was hit byFileSizeComparisonIntegrationTest(nullableLowCardinalityUtf8_javaVsJni,nullableLowCardinalityUtf8_multiChunk_globalDict_javaVsJni,globalDict_nullableMultiChunkUtf8_smallerThanPerChunkDict).Fix
editionExcludedcovers everyEncodingId.WellKnownid outside the enabled editions, plus custom encoders the writer holds, so private candidate lists obey the same policy. This is safe by construction: anything newly excluded would have failed the backstop guard anyway. The regression testWriterEditionGuardTest#cascading_defaultEditions_privateCandidateListsHonorTheEditionfails without the fix. Fixed in #439.