abhigyanpatwari/GitNexus · critical · StorageDeletionError
Refusing to delete storage: the target is the repository…
Error message
Refusing to delete storage: the target is the repository, one of its parents, or a filesystem root
What it means
A StorageDeletionError safety guard thrown before any deletion occurs when the resolved storage path is the repository directory itself, one of its parents, or a filesystem root. Deleting such a path would destroy the source tree or the filesystem, so GitNexus hard-refuses regardless of flags.
Solutions
- Unset or correct GITNEXUS_STORAGE_PATH so it names a dedicated index subdirectory, not the repo or an ancestor.
- Use the default storage location (<repo>/.gitnexus) and retry the deletion.
- Verify the intended path with `gitnexus` status/list-repos before re-running deletion.
- Never set storage paths to /, the repo root, or the home directory.
Example fix
// before GITNEXUS_STORAGE_PATH=/ npx gitnexus clean myrepo // after unset GITNEXUS_STORAGE_PATH && npx gitnexus clean myrepo
Defensive patterns
Strategy: validation
Validate before calling
const resolved = path.resolve(storagePath);
const repo = path.resolve(repoPath);
if (resolved === repo || repo.startsWith(resolved + path.sep) || resolved === path.parse(resolved).root) {
throw new Error('Storage path would delete the repo or a parent directory');
} Type guard
const isSafeDeleteTarget = (storagePath: string, repoPath: string): boolean => {
const s = path.resolve(storagePath), r = path.resolve(repoPath);
return s !== path.parse(s).root && s !== r && !r.startsWith(s + path.sep);
}; Try / catch
try {
await deleteRepoStorage(repoName);
} catch (err) {
if (err instanceof StorageDeletionError && /repository, one of its parents/.test(err.message)) {
console.error('Fix GITNEXUS_STORAGE_PATH: it must be a dedicated subdirectory');
} else throw err;
} Prevention
- Never set GITNEXUS_STORAGE_PATH to /, the repo root, or the home directory.
- Point storage at a dedicated subdirectory created for index data only.
- Dry-run/inspect the resolved path before destructive clean commands.
- Keep external slots outside the repository tree's ancestor chain.
When it happens
Trigger: A registry/lookup produced a storagePath that resolves to the repo root, an ancestor directory (e.g. / or /work), or a mount root — typically via GITNEXUS_STORAGE_PATH set to a root-ish path or a misconfigured external slot.
Common situations: Setting GITNEXUS_STORAGE_PATH=/ or to the repo directory itself; typos like GITNEXUS_STORAGE_PATH=~ (home dir is a parent of the repo); running deletion from cwd at a filesystem root with a relative-path resolution edge case.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Refusing to delete storage: the storage inspection state is
- err.message
- Refusing to delete storage
- Storage requirement not met: foreign external slot is not…
- Unsafe index storage path
AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-09-15).
Data as JSON: /api/errors/7d424c11c543db7b.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/storage/storage-resolver.ts:701
throw new StorageDeletionError(
defaultStoragePath(fallbackRepoPath),
rawStoragePath,
undefined,
error instanceof Error ? error.message : 'the registry storage path is invalid',
);
}
const expectedStoragePath = defaultStoragePath(repoPath);
const storageIsLocal = isRepositoryLocalStoragePath(repoPath, actualStoragePath);
const comparableStorage = comparablePath(actualStoragePath);
const comparableRepo = comparablePath(repoPath);
const comparableRoot = comparablePath(path.parse(actualStoragePath).root);
if (
samePath(comparableStorage, comparableRoot) ||
samePath(comparableStorage, comparableRepo) ||
isPathAncestor(comparableStorage, comparableRepo)
) {
throw new StorageDeletionError(
expectedStoragePath,
actualStoragePath,
undefined,
'the target is the repository, one of its parents, or a filesystem root',
);
}
const inspection = await inspectRegisteredStorage({
path: repoPath,
storagePath: actualStoragePath,
});
const allowedStates: readonly StorageState[] = storageIsLocal
? ['missing', 'empty', 'unowned', 'owned', 'foreign']
: ['owned'];
if (!allowedStates.includes(inspection.state)) {
throw new StorageDeletionError(
expectedStoragePath,
actualStoragePath,View on GitHub (pinned to ac9a4e9abd)