{"record":{"id":"ddecfa5b820e3a15","repo":"abhigyanpatwari/GitNexus","slug":"unable-to-read-eval-server-authentication-from-f","errorCode":null,"errorMessage":"Unable to read eval-server authentication from ${filePath}","messagePattern":"Unable to read eval-server authentication from (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"gitnexus/src/cli/eval-server.ts","lineNumber":107,"sourceCode":"): Promise<string | null> {\n  const directHost = validateHost(raw);\n  if (directHost && directHost !== 'localhost') return directHost;\n  if (directHost !== 'localhost' && !isHostname(raw)) return null;\n\n  try {\n    const address = await resolveHostname(raw);\n    return isIPv4(address) ? address : null;\n  } catch {\n    return null;\n  }\n}\n\nfunction readAuthTokenFile(filePath: string): string | undefined {\n  try {\n    return parseEnv(readFileSync(filePath, 'utf8')).GITNEXUS_AUTH_TOKEN?.trim() || undefined;\n  } catch (error) {\n    if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined;\n    throw new Error(`Unable to read eval-server authentication from ${filePath}`, { cause: error });\n  }\n}\n\n/** Resolve the bearer token from the shell, then .env.local, then .env. */\nexport function resolveEvalServerAuthToken(\n  env: NodeJS.ProcessEnv,\n  cwd: string = process.cwd(),\n): string | undefined {\n  if (Object.hasOwn(env, 'GITNEXUS_AUTH_TOKEN')) {\n    return env.GITNEXUS_AUTH_TOKEN?.trim() || undefined;\n  }\n\n  return (\n    readAuthTokenFile(path.join(cwd, '.env.local')) ?? readAuthTokenFile(path.join(cwd, '.env'))\n  );\n}\n\n/** True only for literal loopback addresses; DNS names are resolved before this check. */","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/d540b00184d71a896261ee02670da9a92d59d8f7/gitnexus/src/cli/eval-server.ts#L89-L125","documentation":"The eval-server attempted to read `.env` / `.env.local` for `GITNEXUS_AUTH_TOKEN` and Node's `parseEnv` threw (ENOENT — file missing — is handled and returns undefined). This means the env file exists but is malformed: `parseEnv` rejects invalid KEY=value lines. The original error is attached via `Error.cause`.","triggerScenarios":"An `.env` line with an invalid KEY=value shape that `node:util.parseEnv` rejects, e.g. a line without `=`, or reserved/unescapeable sequences.","commonSituations":"Manually authored `.env` with unusual formatting; a line copied from a shell script with `export` prefixes or inline comments; merge conflicts leaving garbage in the file.","solutions":["Inspect `.env` and `.env.local` for malformed lines and fix them to KEY=value.","Quote values containing special characters or #.","Set GITNEXUS_AUTH_TOKEN in the shell environment instead of the file to bypass parsing.","If the file is unused, remove it so the ENOENT path applies."],"exampleFix":"# before\nGITNEXUS_AUTH_TOKEN=abc # comment with space\n# after\nGITNEXUS_AUTH_TOKEN=\"abc\"","handlingStrategy":"try-catch","validationCode":"import { parseEnv } from 'node:util';\nimport { readFileSync } from 'node:fs';\n// Pre-flight: ensure the env file parses before starting the server\nfor (const f of ['.env.local', '.env']) {\n  try {\n    parseEnv(readFileSync(f, 'utf8'));\n  } catch (e) {\n    console.error(f + ' is malformed:', e.message);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  resolveEvalServerAuthTokenForHost(host, process.env);\n} catch (e) {\n  if (isEvalServerLoopbackHost(host)) {\n    cliWarn(e.message + ' Continuing without auth on loopback.');\n  } else {\n    throw e; // non-loopback: surface the failure\n  }\n}","preventionTips":["Keep .env/.env.local as simple KEY=value lines; quote values with special chars.","Prefer exporting GITNEXUS_AUTH_TOKEN in the shell for the eval-server."],"tags":["eval-server","env","auth","config"],"backgroundTag":null,"analyzedSha":"d540b00184d71a896261ee02670da9a92d59d8f7","analyzedAt":"2026-08-12T19:50:25.132Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}