{"record":{"id":"0d91ab887665ff43","repo":"canopy-network/canopy","slug":"rollback-target-height-d-exceeds-current-height","errorCode":null,"errorMessage":"rollback target height %d exceeds current height %d","messagePattern":"rollback target height (.+?) exceeds current height (.+?)","errorType":"error_code","errorClass":"ErrCommitDB","httpStatus":null,"severity":"error","filePath":"store/store.go","lineNumber":338,"sourceCode":"\n// Rollback rewinds the store to a previous version (height).\n//\n// It removes all versioned entries above targetVersion, rebuilds the latest state\n// view from historical state at targetVersion, and resets the latest commit pointer.\n// NOTE: Rollback is an offline maintenance operation and must only run while the node is stopped.\nfunc (s *Store) Rollback(targetVersion uint64) lib.ErrorI {\n\tif s.isTxn {\n\t\treturn ErrCommitDB(fmt.Errorf(\"rollback is not supported for nested transactions\"))\n\t}\n\tif targetVersion == 0 {\n\t\treturn ErrCommitDB(fmt.Errorf(\"rollback target height must be >= 1\"))\n\t}\n\ts.mu.Lock()\n\tdefer s.mu.Unlock()\n\n\tcurrentVersion := s.version\n\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}","sourceCodeStart":320,"sourceCodeEnd":356,"githubUrl":"https://github.com/canopy-network/canopy/blob/ee8197d91dd410f6592cb650a94c925ee6dc8bad/store/store.go#L320-L356","documentation":"Rollback rewinds state to an earlier version; it cannot roll forward. If the requested targetVersion is greater than the store's current committed version, the operation is nonsensical and rejected with this error naming both heights.","triggerScenarios":"Calling Rollback(targetVersion) where targetVersion > s.version — e.g. after the DB was already rolled back once, or the operator supplied a height from a different (longer) chain/db.","commonSituations":"Re-running a rollback script twice with the same target height after the first succeeded; restoring a backup and then attempting to roll back to a height that only existed before the backup; copy-pasting a height from another node.","solutions":["Query the store's current version (s.Version()) and choose a targetVersion <= that value","If the operation already succeeded previously, no further rollback is needed — verify current height instead","Ensure the DB you are operating on is the one the target height belongs to"],"exampleFix":"// before\nstore.Rollback(5000) // current height is 4200\n// after\ncurrent := store.Version()\ntarget := uint64(4000)\nif target > current {\n    target = current // clamp or abort\n}\nstore.Rollback(target)","handlingStrategy":"validation","validationCode":"current := st.Version()\nif targetVersion > current {\n    return fmt.Errorf(\"cannot roll forward: target %d > current %d\", targetVersion, current)\n}","typeGuard":null,"tryCatchPattern":"if err := st.Rollback(h); err != nil {\n    if strings.Contains(err.Error(), \"exceeds current height\") {\n        log.Infof(\"store already at or below height %d; nothing to do\", h)\n        return nil\n    }\n    return err\n}","preventionTips":["Read st.Version() first and clamp/abort before calling Rollback","Make rollback scripts idempotent (no-op when already at/below target)","Never copy target heights from other nodes without checking this store's height"],"tags":["store","rollback","argument","versioning"],"backgroundTag":"argument-out-of-range","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"}