{"record":{"id":"3e0993aca62a0954","repo":"abhigyanpatwari/GitNexus","slug":"registered-storage-path-for-repopath-must-be-an-absolute-non","errorCode":null,"errorMessage":"Registered storage path for ${repoPath} must be an absolute, non-empty path.","messagePattern":"Registered storage path for (.+?) must be an absolute, non-empty path\\.","errorType":"validation","errorClass":"InvalidStoragePathError","httpStatus":null,"severity":"error","filePath":"gitnexus/src/storage/storage-resolver.ts","lineNumber":317,"sourceCode":"    if (!Array.isArray(data)) return undefined;\n    entries = data;\n  } catch {\n    return undefined;\n  }\n\n  const resolvedRepoPath = canonicalRegistryPath(repoPath);\n  for (const entry of entries) {\n    if (entry === null || typeof entry !== 'object' || Array.isArray(entry)) continue;\n    const registryEntry = entry as RegistryStorageEntry;\n    if (typeof registryEntry.path !== 'string') continue;\n    if (!samePath(canonicalRegistryPath(registryEntry.path), resolvedRepoPath)) continue;\n    if (registryEntry.storagePath === undefined) {\n      // Pre-external-storage rows have no storagePath. Match readRegistry():\n      // fall through to the repository-local default instead of failing closed.\n      return undefined;\n    }\n    if (typeof registryEntry.storagePath !== 'string') {\n      throw new InvalidStoragePathError(\n        `Registered storage path for ${repoPath} must be an absolute, non-empty path.`,\n      );\n    }\n    return validateConfiguredStoragePath(registryEntry.storagePath);\n  }\n  return undefined;\n};\n\n/** Resolve one repository's complete index directory. */\nexport const resolveStoragePath = (repoPath: string): string => {\n  const resolvedRepoPath = resolveRepoPath(repoPath);\n  const configuredPath = configuredStoragePath();\n  if (configuredPath) return configuredPath;\n\n  const configuredRoot = configuredStorageRoot(resolvedRepoPath);\n  if (configuredRoot) return configuredRoot;\n\n  const registered = registeredStoragePath(resolvedRepoPath);","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/ac9a4e9abd8fd3058c070b72c23402a4f887929a/gitnexus/src/storage/storage-resolver.ts#L299-L335","documentation":"registeredStoragePath looks up a repository's registered storagePath from the mirror registry. If the row carries a storagePath that is not a string (corrupted type, wrong JSON type), it throws InvalidStoragePathError 'Registered storage path for <repoPath> must be an absolute, non-empty path.' Note that rows with storagePath === undefined intentionally fall through to the repo-local default and do NOT throw.","triggerScenarios":"Calling registered() for a repo whose registry row has storagePath set to null, a number, boolean, or object — e.g. a hand-edited registry file, a writer bug storing the wrong type, or a partial migration writing placeholder values.","commonSituations":"Manual edits to the registry/index files; a failed write truncating or corrupting the registry JSON; older tooling or scripts inserting placeholder values like 0 or false into storagePath.","solutions":["Inspect the registry row for that repoPath and fix storagePath to a proper absolute-path string (or delete the field so it falls back to the repo-local default).","Re-register/re-analyze the repo so the registry row is rewritten correctly: node .gitnexus/run.cjs analyze --index-only.","Harden any custom writers so they serialize storagePath as a string and omit it entirely when unknown."],"exampleFix":"// before\n{ \"repoPath\": \"/work/app\", \"storagePath\": 0 }\n// after\n{ \"repoPath\": \"/work/app\", \"storagePath\": \"/var/lib/gitnexus-storage/app-a1b2c3\" }","handlingStrategy":"type-guard","validationCode":"const row = readRegistryRow(repoPath);\nif (row.storagePath !== undefined && typeof row.storagePath !== 'string') {\n  console.warn(`registry storagePath for ${repoPath} has wrong type (${typeof row.storagePath}); fixing row`);\n  delete row.storagePath; // fall back to repo-local default\n}","typeGuard":"const hasValidStoragePath = (row: { storagePath?: unknown }): row is { storagePath?: string } =>\n  row.storagePath === undefined || (typeof row.storagePath === 'string' && row.storagePath.length > 0);","tryCatchPattern":"try {\n  const p = registered(repoPath);\n} catch (e) {\n  if (e instanceof InvalidStoragePathError && e.message.includes('Registered storage path')) {\n    throw new Error(`registry row for ${repoPath} is corrupt; re-run analyze to rewrite it`);\n  }\n  throw e;\n}","preventionTips":["Treat .gitnexus registry files as machine-managed; never hand-edit.","Omit storagePath entirely (not null/0) when unknown so the default fallback applies.","Validate registry JSON shape after any custom tooling writes to it."],"tags":["registry","type-mismatch","storage"],"backgroundTag":"config-type-mismatch","analyzedSha":"ac9a4e9abd8fd3058c070b72c23402a4f887929a","analyzedAt":"2026-09-15T23:29:44.066Z","contentChangedAt":"2026-09-15T23:29:44.066Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}