abhigyanpatwari/GitNexus · error · InvalidStoragePathError
Repository path must be non-empty.
Error message
Repository path must be non-empty.
What it means
resolveRepoPath validates the raw repository path input before path.resolve. A zero-length (or non-string) value is rejected with InvalidStoragePathError('Repository path must be non-empty.'). Every downstream resolver helper (canonicalRepoPath, defaultStoragePath, resolvedRepoPath, requireDeletableStoragePath) funnels through it, so this fires on the first storage API call with an empty repo path.
Solutions
- Supply a valid repository path (e.g. process.cwd() or the project root) to the storage call.
- Check the config/env source that should hold the path; fix the empty value before calling.
- Add an early guard in your caller to fail with a clear message when the path is empty.
- If path comes from argv, validate arg count/presence before invoking storage APIs.
Example fix
// before
const repoPath = config.repoPath ?? '';
const canonical = await canonicalRepoPath(repoPath);
// after
const repoPath = config.repoPath ?? process.cwd();
if (typeof repoPath !== 'string' || repoPath.length === 0) throw new Error('repoPath is required');
const canonical = await canonicalRepoPath(repoPath); Defensive patterns
Strategy: validation
Validate before calling
if (typeof repoPath !== 'string' || repoPath.trim().length === 0) {
throw new Error('repoPath is required and must be a non-empty string');
} Type guard
const isNonEmptyString = (v: unknown): v is string => typeof v === 'string' && v.length > 0;
Try / catch
try {
return await canonicalRepoPath(repoPath);
} catch (e) {
if (e instanceof InvalidStoragePathError) throw new Error(`bad repo path input: ${e.message}`);
throw e;
} Prevention
- Default repoPath to process.cwd() instead of an empty string.
- Validate CLI/config path fields at startup before any storage call.
- Never pass optional/possibly-undefined values straight into storage APIs.
When it happens
Trigger: Passing '' (or undefined coerced via String()) as the repoPath argument to canonicalRepoPath/defaultStoragePath/resolvedRepoPath, or a config/env value that resolves to an empty string.
Common situations: Missing or empty CLI flag / config field for the repository path; env var like GITNEXUS_... left unset and defaulted to ''; calling the storage API programmatically before the caller supplied a repo root.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- entry does not identify a repo — name and storagePath must…
- parsedfile-store: dropped malformed/over-bound sites at…
- parsedfile-store: rejected shard entries at load (untrusted…
- Refusing to adopt branch metadata: storage is not owned by…
- must not be blank.
AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-09-15).
Data as JSON: /api/errors/96ae02b4efad5f76.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/storage/storage-resolver.ts:175
const samePath = (left: string, right: string): boolean =>
process.platform === 'win32' ? left.toLowerCase() === right.toLowerCase() : left === right;
const isRepositoryLocalStoragePath = (repoPath: string, storagePath: string): boolean =>
samePath(comparablePath(defaultStoragePath(repoPath)), comparablePath(storagePath));
const isMissingFilesystemError = (error: unknown): boolean => {
const code = (error as NodeJS.ErrnoException)?.code;
return code === 'ENOENT' || code === 'ENOTDIR';
};
const filesystemErrorDetail = (error: unknown): string => {
const code = (error as NodeJS.ErrnoException)?.code;
return code ? `${code}: ${(error as Error)?.message ?? String(error)}` : String(error);
};
const resolveRepoPath = (value: string): string => {
if (typeof value !== 'string' || value.length === 0) {
throw new InvalidStoragePathError('Repository path must be non-empty.');
}
if (value.includes('\0')) {
throw new InvalidStoragePathError('Repository path must not contain a NUL character.');
}
return path.resolve(value);
};
const validateAbsolutePath = (value: string, label: string): string => {
if (typeof value !== 'string' || value.length === 0) {
throw new InvalidStoragePathError(`${label} must be an absolute, non-empty path.`);
}
if (value.includes('\0')) {
throw new InvalidStoragePathError(`${label} must not contain a NUL character.`);
}
if (!path.isAbsolute(value)) {
throw new InvalidStoragePathError(`${label} must be an absolute path.`);
}
return path.resolve(value);View on GitHub (pinned to ac9a4e9abd)