{"record":{"id":"206cbd67aa2eb15f","repo":"elastic/elasticsearch","slug":"transport-version-base-id-is-missing-patch-ids","errorCode":null,"errorMessage":"Transport version base id {} is missing patch ids between {} and {}","messagePattern":"Transport version base id (.+?) is missing patch ids between (.+?) and (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/transport/ValidateTransportVersionResourcesTask.java","lineNumber":298,"sourceCode":"        }\n    }\n\n    private void validateBase(int base, List<IdAndDefinition> ids) {\n        // TODO: switch this to a fully dense check once all existing transport versions have been migrated\n        IdAndDefinition previous = ids.getLast();\n        for (int ndx = ids.size() - 2; ndx >= 0; --ndx) {\n            IdAndDefinition current = ids.get(ndx);\n\n            if (previous.id().equals(current.id())) {\n                Path existingDefinitionPath = getResources().get().getDefinitionPath(previous.definition());\n                throwDefinitionFailure(\n                    current.definition(),\n                    \"contains id \" + current.id() + \" already defined in [\" + existingDefinitionPath + \"]\"\n                );\n            }\n\n            if (getShouldValidateDensity().get() && previous.id().complete() - 1 != current.id().complete()) {\n                throw new IllegalStateException(\n                    \"Transport version base id \" + base + \" is missing patch ids between \" + current.id() + \" and \" + previous.id()\n                );\n            }\n            previous = current;\n        }\n    }\n\n    private void validatePrimaryIds(\n        TransportVersionResourcesService resources,\n        Map<String, TransportVersionUpperBound> upperBounds,\n        Map<String, TransportVersionDefinition> allDefinitions\n    ) {\n        // first id is always the highest within a definition, and validated earlier\n        // note the first element is actually the highest because the id comparator is in descending order\n        var sortedDefinitions = allDefinitions.values().stream().sorted(Comparator.comparing(d -> d.ids().getFirst())).toList();\n        TransportVersionDefinition highestDefinition = sortedDefinitions.getFirst();\n        TransportVersionId highestId = highestDefinition.ids().getFirst();\n","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/transport/ValidateTransportVersionResourcesTask.java#L280-L316","documentation":"Thrown by validateBase in ValidateTransportVersionResourcesTask when density validation is enabled and the patch IDs within a single base ID are not perfectly contiguous. Transport version IDs are allocated densely (base + patch), so a gap between consecutive patch IDs signals a leaked/unused ID that breaks the compact allocation scheme.","triggerScenarios":"A patch ID was deleted from a definition without recompacting; a definition file lists IDs [base.0, base.2] skipping base.1; the density flag (-D...shouldValidateDensity) is on and the sorted-descending IDs within one base show previous.complete()-1 != current.complete().","commonSituations":"Removing an obsolete transport version from a definition file but leaving its slot; merging two definition files and dropping an intermediate patch; hand-editing ID lists in the resource YAML/CSV.","solutions":["Open the definition file for the named base ID and renumber patch IDs so they are contiguous from base.0 upward with no gaps.","If a gap is intentional during migration, disable density validation temporarily via the task's shouldValidateDensity property and add a TODO, then re-enable after migration (see the existing TODO in validateBase).","Regenerate resources with './gradlew generateTransportVersion' after fixing the file to confirm consistency."],"exampleFix":"// before: ids in definition for base 8800000 are [8800000, 8800002]  (8800001 missing)\n// after:  renumber to [8800000, 8800001] so patches are dense","handlingStrategy":"validation","validationCode":"// When editing a definition file's ID list, ensure patches within a base are contiguous:\n// ids.stream().mapToInt(id -> id.complete()).sorted().toArray() should have adjacent diffs of 1 within the same base.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid hand-editing ID lists; regenerate via './gradlew generateTransportVersion'.","If you must remove a patch ID, renumber the remaining patches to stay dense.","Disable density validation only during the documented migration window, with a tracked TODO."],"tags":["build","gradle","transport-version","validation","density-check"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}