{"record":{"id":"b1e068a2a9be114c","repo":"pinpoint-apm/pinpoint","slug":"unexpected-schema-change-log-id-expected","errorCode":null,"errorMessage":"Unexpected schema change log id, expected : ","messagePattern":"Unexpected schema change log id, expected : ","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hbase/hbase-schema/src/main/java/com/navercorp/pinpoint/hbase/schema/core/ChangeSetManager.java","lineNumber":101,"sourceCode":"            i++;\n        }\n        if (i >= changeSets.size()) {\n            return Collections.emptyList();\n        }\n        return new ArrayList<>(changeSets.subList(i, changeSets.size()));\n    }\n\n    private List<SchemaChangeLog> sortSchemaChangeLogs(List<SchemaChangeLog> schemaChangeLogs) {\n        List<SchemaChangeLog> sortedSchemaChangeLogs = new ArrayList<>(schemaChangeLogs);\n        sortedSchemaChangeLogs.sort(Comparator.comparingInt(SchemaChangeLog::getExecOrder));\n        return sortedSchemaChangeLogs;\n    }\n\n    private void verifyChangeLog(SchemaChangeLog schemaChangeLog, ChangeSet changeSet, int expectedOrder) {\n        String changeSetId = changeSet.getId();\n        String schemaChangeLogId = schemaChangeLog.getId();\n        if (!changeSetId.equals(schemaChangeLogId)) {\n            throw new IllegalArgumentException(\"Unexpected schema change log id, expected : \" + changeSetId + \" , was : \" + schemaChangeLogId);\n        }\n\n        CheckSum actualCheckSum = schemaChangeLog.getCheckSum();\n        CheckSum expectedCheckSum = CheckSum.compute(actualCheckSum.getVersion(), changeSet.getValue());\n        if (!expectedCheckSum.equals(actualCheckSum)) {\n            throw new IllegalArgumentException(\"Unexpected schema change log check sum for : \" + schemaChangeLogId);\n        }\n        int actualOrder = schemaChangeLog.getExecOrder();\n        if (expectedOrder != actualOrder) {\n            throw new IllegalArgumentException(\"Unexpected schema change log execution order for \" + schemaChangeLogId + \", expected : \" + expectedOrder + \", was : \" + actualOrder);\n        }\n    }\n}\n","sourceCodeStart":83,"sourceCodeEnd":115,"githubUrl":"https://github.com/pinpoint-apm/pinpoint/blob/744c3d3075e595656abb1ae331ad2c0e4c9eb996/hbase/hbase-schema/src/main/java/com/navercorp/pinpoint/hbase/schema/core/ChangeSetManager.java#L83-L115","documentation":"ChangeSetManager.verifyChangeLog validates each persisted HBase schema change log against the corresponding ChangeSet definition. If the change log's id does not equal the ChangeSet id, it throws IllegalArgumentException, indicating the applied-change history on disk does not match the change sets shipped in the application.","triggerScenarios":"Calling getExecutedChangeSets or filterExecutedChangeSets when a SchemaChangeLog row read from HBase has an id different from the ChangeSet with the same position/order — typically after editing or renaming a change set id that was already applied.","commonSituations":"A developer changed a changeSet's id in a newer release while old change logs remain in the schema change log table, or change logs from a different database/pinpoint environment were written to the same table.","solutions":["Restore the original changeSet id so it matches the stored change log, or update the change log table to the new id.","Never mutate ids of already-applied change sets; add a new change set instead.","Confirm you are pointing at the correct HBase namespace/table — mismatched environments can hold foreign change logs."],"exampleFix":"// before\nprivate static final String CHANGELOG_ID = \"hbase-change-2-v2\"; // renamed after being applied\n// after\nprivate static final String CHANGELOG_ID = \"hbase-change-2-v1\"; // keep original id; add a NEW change set for new work","handlingStrategy":"validation","validationCode":"// Before deploying, diff changeSet ids against stored change logs\nSet<String> appliedIds = executedChangeLogs.stream()\n    .map(SchemaChangeLog::getId).collect(Collectors.toSet());\nSet<String> definedIds = changeSets.stream().map(ChangeSet::getId).collect(Collectors.toSet());\nif (!appliedIds.containsAll(definedIds) && !Collections.disjoint(appliedIds, definedIds)) {\n    throw new IllegalStateException(\"ChangeSet ids drifted from applied change logs: \" + appliedIds);\n}","typeGuard":null,"tryCatchPattern":"try {\n    manager.getExecutedChangeSets(changeSets);\n} catch (IllegalArgumentException e) {\n    logger.error(\"Change log verification failed: {}\", e.getMessage());\n}","preventionTips":["Treat applied changeSet ids as immutable; never rename after release.","Add a CI check comparing change set ids against the production change log table.","Keep separate change log tables per environment."],"tags":["hbase","schema-migration","id-mismatch"],"backgroundTag":"schema-validation-failed","analyzedSha":"744c3d3075e595656abb1ae331ad2c0e4c9eb996","analyzedAt":"2026-09-07T18:48:45.289Z","contentChangedAt":"2026-09-07T18:48:45.289Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}