abhigyanpatwari/GitNexus · error · GitNexusRcError
Could not read
Error message
Could not read ${GITNEXUS_RC_FILENAME}: ${(err as Error).message} What it means
loadAnalyzeConfig could not read .gitnexusrc for a reason other than 'file does not exist' (ENOENT returns undefined — no config is the normal case). Typical causes surfaced through the wrapped message: EACCES (permission denied), EISDIR (the path is a directory), or EMFILE/ENFILE (fd exhaustion). The underlying Node error message is appended.
Solutions
- Inspect the file: ls -la .gitnexusrc and stat it — the appended Node message tells you the exact code (EACCES vs EISDIR)
- Fix permissions/ownership: chmod 644 .gitnexusrc (or chown to the running user)
- If it is a directory, remove it and recreate as a regular JSON file
- In containers, ensure the volume mount and run uid can read the repo root
Example fix
# before $ ls -la .gitnexusrc # -rw------- root root # after $ sudo chown $(id -u):$(id -g) .gitnexusrc && chmod 644 .gitnexusrc
Defensive patterns
Strategy: try-catch
Validate before calling
import { accessSync, constants } from 'node:fs';
try {
accessSync('.gitnexusrc', constants.R_OK);
} catch {
console.error('.gitnexusrc is not readable by this uid — fix ownership/permissions');
} Try / catch
try {
loadAnalyzeConfig(repoRoot);
} catch (err) {
if (err instanceof GitNexusRcError && err.message.includes('Could not read')) {
const code = (err as NodeJS.ErrnoException).code;
if (code === 'EACCES') { /* chmod/chown the file */ }
if (code === 'EISDIR') { /* it is a directory — recreate as a file */ }
}
} Prevention
- Create .gitnexusrc as the same user that runs analyze (avoid sudo-created root-owned files)
- In Docker, ensure the run uid owns or can read repo-root files
- Treat non-ENOENT read failures as environment problems, not config-syntax problems
When it happens
Trigger: chmod 000 .gitnexusrc or ownership mismatch under root-vs-user runs; .gitnexusrc accidentally created as a directory; read-only container filesystems; too many open files in long-lived processes.
Common situations: Running analyze in Docker as a different uid than the file owner; sudo-created .gitnexusrc later read by a normal user; CI cache restoring the path as a directory; security tooling locking the file.
Related errors
- exceeds bytes
- must be a regular file
- GitNexus could not move the LadybugDB WAL sidecar at
- is not valid JSON: . Expected a JSON object such as .
- must contain a JSON object.
AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-09-01).
Data as JSON: /api/errors/8808c7ca7dba36b7.
Report an issue: GitHub.
Appendix: source
Thrown at gitnexus/src/cli/analyze-config.ts:368
}
return out;
};
/**
* Locate, read, parse, validate, and normalize `.gitnexusrc` at `repoRoot`.
*
* @returns the normalized config defaults, or `undefined` when no file exists
* (the normal case). Throws {@link GitNexusRcError} on any problem.
*/
export function loadAnalyzeConfig(repoRoot: string): Partial<AnalyzeOptions> | undefined {
const filePath = path.join(repoRoot, GITNEXUS_RC_FILENAME);
let raw: string;
try {
raw = fs.readFileSync(filePath, 'utf-8');
} catch (err) {
if ((err as NodeJS.ErrnoException)?.code === 'ENOENT') return undefined;
throw new GitNexusRcError(`Could not read ${GITNEXUS_RC_FILENAME}: ${(err as Error).message}`);
}
return parseAnalyzeConfig(raw);
}
/** Load `.gitnexusrc` through the strict bounded reader used by watch mode. */
export async function loadAnalyzeConfigStrict(
repoRoot: string,
): Promise<Partial<AnalyzeOptions> | undefined> {
let raw: string | null;
try {
raw = await readRepoControlFile(repoRoot, GITNEXUS_RC_FILENAME);
} catch (err) {
throw new GitNexusRcError(`Could not read ${GITNEXUS_RC_FILENAME}: ${(err as Error).message}`);
}
return raw === null ? undefined : parseAnalyzeConfig(raw);
}
View on GitHub (pinned to ac9a4e9abd)