abhigyanpatwari/GitNexus · error · InvalidStoragePathError
Index storage path is not a directory
Error message
Index storage path is not a directory: ${resolved} What it means
An InvalidStoragePathError from ensureStoragePathWritable, thrown after mkdir/stat when the configured storage path resolves to something that is not a directory (e.g. a regular file or symlink to a file). GitNexus requires the index storage location to be a real, writable directory before an analysis takes its lock.
Solutions
- Remove or rename the file currently occupying the storage path so the directory can be created.
- Correct GITNEXUS_STORAGE_PATH to point at a directory (or a path that does not yet exist and can be created).
- Check for a stale symlink with `ls -la` and fix or remove it.
- Re-run the command; the resolver will mkdir the directory and re-validate permissions.
Example fix
// before GITNEXUS_STORAGE_PATH=/tmp/index.tar.gz npx gitnexus analyze // after rm /tmp/index.tar.gz && GITNEXUS_STORAGE_PATH=/tmp/myrepo-index npx gitnexus analyze
Defensive patterns
Strategy: try-catch
Validate before calling
const st = await fsp.stat(storagePath).catch(() => null);
if (st && !st.isDirectory()) {
throw new Error(`GITNEXUS_STORAGE_PATH points at a non-directory: ${storagePath}`);
} Try / catch
try {
await ensureStoragePathWritable(storagePath);
} catch (err) {
if (err instanceof InvalidStoragePathError && /not a directory/.test(err.message)) {
fs.rmSync(storagePath, { force: true }); // remove the offending file, then retry
} else throw err;
} Prevention
- Check `ls -la` on GITNEXUS_STORAGE_PATH: it must be absent or a directory.
- Don't point storage paths at files, tarballs, or logs.
- Watch for symlinks retargeted from directories to files after volume changes.
- Let GitNexus create the directory (mkdir recursive) rather than pre-creating it as a file.
When it happens
Trigger: Running analyze (or any flow calling ensureStoragePathWritable) with GITNEXUS_STORAGE_PATH pointing at an existing regular file, or where mkdir recursive:true was a no-op because a file occupies the path.
Common situations: GITNEXUS_STORAGE_PATH accidentally set to a file (e.g. a tarball or log); a stale file left where a directory used to be; a symlink retargeted from a directory to a file; a mount point replaced by a file after a volume change.
Related errors
- Could not read
- Could not remove the shadowed branch sub-index; keeping its…
- exceeds bytes
- must be a regular file
- Storage requirement not met: state is
AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-09-15).
Data as JSON: /api/errors/9f3689326a8ac0b0.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/storage/storage-resolver.ts:733
: ['owned'];
if (!allowedStates.includes(inspection.state)) {
throw new StorageDeletionError(
expectedStoragePath,
actualStoragePath,
inspection,
`the storage inspection state is "${inspection.state}"`,
);
}
return actualStoragePath;
};
/** Ensure a selected index directory is usable before an analysis takes its lock. */
export const ensureStoragePathWritable = async (storagePath: string): Promise<void> => {
const resolved = validateConfiguredStoragePath(storagePath);
await fsp.mkdir(resolved, { recursive: true });
const stat = await fsp.stat(resolved);
if (!stat.isDirectory()) {
throw new InvalidStoragePathError(`Index storage path is not a directory: ${resolved}`);
}
await fsp.access(resolved, fs.constants.R_OK | fs.constants.W_OK);
};
View on GitHub (pinned to ac9a4e9abd)