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

  1. Stop sharing the storage path: give this repo its own storage directory (default <repo>/.gitnexus) and re-run.
  2. If GITNEXUS_STORAGE_PATH is set, clear it or set it to a slot created for this repository.
  3. Re-create the index fresh for this repository rather than adopting the foreign slot.
  4. 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

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


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)