Environment
- nanobrew: v0.1.205
- macOS: 26.5.1
- arch: arm64
/opt/nb: absent
Summary
Nanobrew saves a keg into store-relocated/<bottle-sha> even when the whole-file relocation could not run. That incomplete snapshot is then treated as fully relocated: nb reinstall restores it, skips relocation, and returns before the post-install probe.
This means that creating /opt/nb later does not heal the package. The user must know to delete store-relocated manually. This is both the pre-v0.1.204 cache-invalidation follow-up mentioned in #347 and an ongoing way for v0.1.205 itself to create new poisoned snapshots.
Reproduction
With /opt/nb absent:
The first install warns:
nb: note: /opt/nb short-prefix symlink unavailable — Mach-O .rodata not relocated; run `sudo nb init` and reinstall affected packages
The resulting libperl.dylib still contains its Homebrew @INC paths:
strings -a /opt/nanobrew/prefix/Cellar/perl/5.42.2/lib/perl5/5.42/darwin-thread-multi-2level/CORE/libperl.dylib \
| rg '/opt/homebrew'
The same paths are saved in the relocated snapshot:
/opt/nanobrew/store-relocated/11266b9a2528911df242d82ec041ee91a50c3374d03c9401b558e521b5569916/lib/perl5/5.42/darwin-thread-multi-2level/CORE/libperl.dylib
Reinstalling the same artifact:
completed in 179 ms with no short-prefix warning and no failed post-install probe:
✓ perl
==> Done in 179.4ms
Afterward, libperl.dylib still contained /opt/homebrew, and Config.pm was still loaded from Homebrew.
Scope observed locally
After removing the temporary Perl test snapshot, the existing installation still had:
- 107
store-relocated snapshots containing /opt/homebrew
- 10 affected snapshots created after v0.1.205 was released
- 324 foreign-prefix files in currently selected kegs across 45 formulae
So this is not limited to pre-fix cache entries.
Relevant implementation
src/main.zig fast-paths on hasRelocatedEntry(bottle_sha256), materializes it, links it, runs postinstall, and returns before relocation and probing.
- The normal path calls
saveRelocatedEntry after relocateKeg, even though the short-prefix fallback may have knowingly left .rodata unrelocated.
src/store/store.zig keys snapshots only by artifact SHA. It stores no relocation schema/version, target prefix, short-prefix availability, or completeness marker.
Expected
- Do not save a relocated snapshot when required relocation was incomplete.
- Version or validate relocated-cache entries before reuse.
- Invalidate snapshots produced by pre-fix versions or incompatible relocation modes.
- A cached reinstall should still run appropriate health/probe validation.
- Once
/opt/nb becomes available, reinstalling should repair rather than perpetuate the foreign-prefix keg.
Refs #347, #355, and #317.
Environment
/opt/nb: absentSummary
Nanobrew saves a keg into
store-relocated/<bottle-sha>even when the whole-file relocation could not run. That incomplete snapshot is then treated as fully relocated:nb reinstallrestores it, skips relocation, and returns before the post-install probe.This means that creating
/opt/nblater does not heal the package. The user must know to deletestore-relocatedmanually. This is both the pre-v0.1.204 cache-invalidation follow-up mentioned in #347 and an ongoing way for v0.1.205 itself to create new poisoned snapshots.Reproduction
With
/opt/nbabsent:The first install warns:
The resulting
libperl.dylibstill contains its Homebrew@INCpaths:The same paths are saved in the relocated snapshot:
Reinstalling the same artifact:
completed in 179 ms with no short-prefix warning and no failed post-install probe:
Afterward,
libperl.dylibstill contained/opt/homebrew, andConfig.pmwas still loaded from Homebrew.Scope observed locally
After removing the temporary Perl test snapshot, the existing installation still had:
store-relocatedsnapshots containing/opt/homebrewSo this is not limited to pre-fix cache entries.
Relevant implementation
src/main.zigfast-paths onhasRelocatedEntry(bottle_sha256), materializes it, links it, runs postinstall, and returns before relocation and probing.saveRelocatedEntryafterrelocateKeg, even though the short-prefix fallback may have knowingly left.rodataunrelocated.src/store/store.zigkeys snapshots only by artifact SHA. It stores no relocation schema/version, target prefix, short-prefix availability, or completeness marker.Expected
/opt/nbbecomes available, reinstalling should repair rather than perpetuate the foreign-prefix keg.Refs #347, #355, and #317.