abhigyanpatwari/GitNexus · error · StorageRequirementError
Storage requirement not met: foreign external slot is not…
Error message
Storage requirement not met: foreign external slot is not adoptable
What it means
A StorageRequirementError raised when the inspected storage is in state 'foreign' but the slot's path does not correspond to this checkout's own .gitnexus (isRepositoryLocalStoragePath fails). Even if the caller opted into foreign slots via analyze/index --force, GitNexus refuses to adopt an external slot that names a different repository, because adopting it would destroy or overwrite another repo's index.
Solutions
- Stop sharing the storage path: give this repo its own storage directory (default <repo>/.gitnexus) and re-run.
- If GITNEXUS_STORAGE_PATH is set, clear it or set it to a slot created for this repository.
- Re-create the index fresh for this repository rather than adopting the foreign slot.
- Check `gitnexus list-repos` / inspection metadata to see which repo owns the external slot before reusing it.
Example fix
// before GITNEXUS_STORAGE_PATH=/data/indexes/other-repo npx gitnexus analyze --force // after unset GITNEXUS_STORAGE_PATH && npx gitnexus analyze
Defensive patterns
Strategy: validation
Validate before calling
const inspection = await inspectStoragePath(storagePath);
if (inspection.state === 'foreign' && inspection.repoPath !== process.cwd()) {
throw new Error('External storage slot belongs to another repo: ' + inspection.repoPath);
} Type guard
const isOwnStorage = (i: StorageInspection): boolean => i.state !== 'foreign' || isRepositoryLocalStoragePath(i.repoPath, i.storagePath);
Try / catch
try {
await requireStoragePath(repoPath, { allowedStates: [...,'foreign'] });
} catch (err) {
if (err instanceof StorageRequirementError && err.inspection.state === 'foreign') {
// re-point storage at this repo's own .gitnexus and retry
} else throw err;
} Prevention
- Never point GITNEXUS_STORAGE_PATH at a slot created for a different repository.
- One external storage slot per repository; name directories after the repo.
- Check `gitnexus list-repos` ownership metadata before adopting shared slots.
- After moving/renaming a repo, re-index instead of reusing old external slots.
When it happens
Trigger: Running analyze/index --force while GITNEXUS_STORAGE_PATH (or the resolved storage path) points to an external slot whose registered repoPath is a different repository than the one being analyzed.
Common situations: Sharing one external index directory between multiple repos via GITNEXUS_STORAGE_PATH; copying a .gitnexus directory from another project; a moved/renamed repo reusing an old external slot.
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
- Refusing to delete storage: the target is the repository…
- Analysis not finalized: missing
- Could not remove the shadowed branch sub-index; keeping its…
- DiskBackedScopeTree.byId is unsupported…
AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-09-15).
Data as JSON: /api/errors/d3f3dd68d202b871.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/storage/storage-resolver.ts:622
path: string;
storagePath: string;
}): Promise<StorageInspection> => inspectStoragePath(entry.storagePath, entry.path);
const requireInspectedStoragePath = (
inspection: StorageInspection,
requirements: StorageRequirements,
): string => {
if (!requirements.allowedStates.includes(inspection.state)) {
throw new StorageRequirementError(inspection, requirements);
}
// `foreign` is only adoptable for this checkout's own `.gitnexus`. An
// external slot that names another repository stays rejected even when the
// caller opted into `foreign` (analyze/index --force).
if (
inspection.state === 'foreign' &&
!isRepositoryLocalStoragePath(inspection.repoPath, inspection.storagePath)
) {
throw new StorageRequirementError(inspection, {
...requirements,
allowedStates: requirements.allowedStates.filter((state) => state !== 'foreign'),
});
}
if (requirements.requireCodeIndexDB && !inspection.hasCodeIndexDB) {
throw new StorageRequirementError(inspection, requirements);
}
return inspection.storagePath;
};
/** Resolve and validate storage selected from a repository path. */
export const requireStoragePath = async (
repoPath: string,
requirements: StorageRequirements,
): Promise<string> =>
requireInspectedStoragePath(await inspectResolvedStorage(repoPath), requirements);
/** Validate the exact storage path persisted in a registry entry. */View on GitHub (pinned to ac9a4e9abd)