abhigyanpatwari/GitNexus · error · StorageRequirementError

Storage requirement not met: state is

Error message

Storage requirement not met: state is "${inspection.state}"

What it means

This is a StorageRequirementError thrown by requireInspectedStoragePath in storage-resolver.ts when the inspected storage directory's state (e.g. 'missing', 'foreign', 'owned', 'unowned') is not among the states the caller declared as acceptable. GitNexus refuses to proceed against a storage slot whose ownership/integrity state does not satisfy the operation's requirements, to protect an index that belongs to another checkout or is unusable. The message embeds the actual state via inspection.state.

Solutions

  1. Read the 'state' value in the error message and reconcile it with what the command needs — usually by re-running analyze to create/claim the storage directory.
  2. Remove or fix the stale .gitnexus directory (or GITNEXUS_STORAGE_PATH) so the inspection yields an allowed state, then re-run.
  3. If the foreign-slot case is intentional, use the documented --force option of analyze/index, which opts into adoptable foreign slots.
  4. Point GITNEXUS_STORAGE_PATH at the correct slot that belongs to this checkout instead of another repository's.

Example fix

// before
GITNEXUS_STORAGE_PATH=/shared/index-cache npx gitnexus analyze
// after (point at this repo's own slot, or let it default to <repo>/.gitnexus)
unset GITNEXUS_STORAGE_PATH && npx gitnexus analyze
Defensive patterns

Strategy: try-catch

Validate before calling

import { inspectStoragePath } from './storage-resolver.js';
const inspection = await inspectStoragePath(storagePath);
if (!['missing','empty','unowned','owned'].includes(inspection.state)) {
  throw new Error(`Storage not usable: state=${inspection.state}`);
}

Type guard

const isAllowedState = (s: string): s is StorageState =>
  ['missing','empty','unowned','owned','foreign'].includes(s);

Try / catch

try {
  await requireStoragePath(repoPath, { allowedStates: ['owned'] });
} catch (err) {
  if (err instanceof StorageRequirementError) {
    console.error(`Storage state is ${err.inspection.state}; re-run analyze or fix GITNEXUS_STORAGE_PATH`);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling requireStoragePath / analyze / index against a repo whose .gitnexus storage inspection returns a state not listed in requirements.allowedStates — e.g. storage belongs to a foreign repository, or an 'owned' slot is required but the directory is 'missing' or 'empty'.

Common situations: Running analyze in a repo whose .gitnexus was created by a different checkout; GITNEXUS_STORAGE_PATH pointing at a slot named for another repo; a deleted or never-created storage directory when the command requires an existing index.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-09-15). Data as JSON: /api/errors/3468b5c39b2ef80e. Report an issue: GitHub.

Appendix: source

Thrown at gitnexus/src/storage/storage-resolver.ts:613

  }
  return inspectStoragePath(storagePath, repoPath);
};

/**
 * Inspect a registry-selected slot without allowing an environment override to
 * redirect the entry to another repository's storage.
 */
export const inspectRegisteredStorage = async (entry: {
  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;
};

View on GitHub (pinned to ac9a4e9abd)