{"record":{"id":"b20c1dcb87eb7fe4","repo":"canopy-network/canopy","slug":"missing-commit-id-at-height-d","errorCode":null,"errorMessage":"missing commit id at height %d","messagePattern":"missing commit id at height (.+?)","errorType":"error_code","errorClass":"ErrStoreGet","httpStatus":null,"severity":"error","filePath":"store/store.go","lineNumber":355,"sourceCode":"\tif targetVersion > currentVersion {\n\t\treturn ErrCommitDB(fmt.Errorf(\"rollback target height %d exceeds current height %d\", targetVersion, currentVersion))\n\t}\n\tif targetVersion == currentVersion {\n\t\treturn nil\n\t}\n\n\tsnapshot := s.db.NewSnapshot()\n\tdefer snapshot.Close()\n\n\t// Ensure the target commit exists so we can repoint the latest commit id.\n\ttargetReader := NewVersionedStore(snapshot, nil, targetVersion)\n\ttargetTx := NewTxn(targetReader, nil, nil, false, false, true)\n\ttargetCommitID, err := targetTx.Get(s.commitIDKey(targetVersion))\n\tif err != nil {\n\t\treturn err\n\t}\n\tif len(targetCommitID) == 0 {\n\t\treturn ErrStoreGet(fmt.Errorf(\"missing commit id at height %d\", targetVersion))\n\t}\n\n\tbatch := s.db.NewBatch()\n\tdefer batch.Close()\n\n\tminVersion := targetVersion + 1\n\taffectedStateKeys := make(map[string][]byte)\n\tfor _, prefix := range [][]byte{\n\t\thistoricStatePrefix,\n\t\tindexerPrefix,\n\t\tstateCommitIDPrefix,\n\t} {\n\t\tif err = s.pruneVersionWindow(\n\t\t\tsnapshot,\n\t\t\tbatch,\n\t\t\tprefix,\n\t\t\tminVersion,\n\t\t\tcurrentVersion,","sourceCodeStart":337,"sourceCodeEnd":373,"githubUrl":"https://github.com/canopy-network/canopy/blob/ee8197d91dd410f6592cb650a94c925ee6dc8bad/store/store.go#L337-L373","documentation":"To rebuild state at the target version, Rollback reads the stored commit ID for that height via the commit-ID index. If the index entry is absent or empty, the rollback cannot proceed safely, so it fails with this error identifying the height.","triggerScenarios":"Calling Rollback(targetVersion) where the commitIDKey(targetVersion) record is missing — e.g. the height never had a committed block, the index was corrupted/truncated by a prior partial rollback, or an empty value was written at that key.","commonSituations":"Rolling back to a height that was skipped (no block committed at that height); a database that was restored from a checkpoint missing older commit records; corruption from an aborted previous maintenance run.","solutions":["Choose a target height that actually has a committed block (verify against block/commit records)","Inspect the commit-ID keyspace to confirm which heights have commit IDs before rolling back","Restore from a consistent checkpoint/backup if the commit-ID index is corrupted"],"exampleFix":"// before\nstore.Rollback(targetHeight) // no commit at targetHeight\n// after\nif !hasCommitIDAt(store, targetHeight) {\n    targetHeight = lastCommittedHeightBelow(store, targetHeight)\n}\nstore.Rollback(targetHeight)","handlingStrategy":"validation","validationCode":"reader := store.NewReaderAt(currentVersion) // or snapshot\nif _, err := reader.Get(store.CommitIDKey(targetVersion)); err != nil || len(v)==0 {\n    return fmt.Errorf(\"no commit id at height %d; pick a committed height\", targetVersion)\n}","typeGuard":null,"tryCatchPattern":"if err := st.Rollback(h); err != nil {\n    if strings.Contains(err.Error(), \"missing commit id\") {\n        // height has no committed block; fall back to nearest committed height\n        return st.Rollback(nearestCommittedHeight(h))\n    }\n    return err\n}","preventionTips":["Roll back only to heights verified in the block/commit index","Restore from a consistent checkpoint if the commit-ID index may be truncated","After any failed maintenance run, audit the commit-ID keyspace before retrying"],"tags":["store","rollback","state","index"],"backgroundTag":"record-not-found","analyzedSha":"ee8197d91dd410f6592cb650a94c925ee6dc8bad","analyzedAt":"2026-09-06T09:30:15.973Z","contentChangedAt":"2026-09-06T09:30:15.973Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}