{"record":{"id":"d85e441a0b2aa27b","repo":"abhigyanpatwari/GitNexus","slug":"gitnexus-mcp-read-only-must-be-0-or-1","errorCode":null,"errorMessage":"GITNEXUS_MCP_READ_ONLY must be 0 or 1.","messagePattern":"GITNEXUS_MCP_READ_ONLY must be 0 or 1\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"gitnexus/src/mcp/read-only-policy.ts","lineNumber":27,"sourceCode":"  'detect_changes',\n  'check',\n  'impact',\n  'explain',\n  'pdg_query',\n  'route_map',\n  'tool_map',\n  'shape_check',\n  'api_impact',\n  'trace',\n]);\n\nconst MCP_READ_ONLY_ALIASES = new Set(['search', 'explore', 'overview']);\n\nexport function resolveMcpReadOnlyMode(env: NodeJS.ProcessEnv = process.env): boolean {\n  const value = env.GITNEXUS_MCP_READ_ONLY?.trim();\n  if (value === undefined || value === '' || value === '0') return false;\n  if (value === '1') return true;\n  throw new Error('GITNEXUS_MCP_READ_ONLY must be 0 or 1.');\n}\n\nexport function assertMcpReadOnlyToolCall(\n  toolName: string,\n  args: Record<string, unknown> | undefined,\n  readOnly: boolean,\n): void {\n  if (!readOnly) return;\n  if (!MCP_READ_ONLY_TOOLS.has(toolName) && !MCP_READ_ONLY_ALIASES.has(toolName)) {\n    throw new Error(`Tool \"${toolName}\" is not available in GitNexus MCP read-only mode.`);\n  }\n  if (typeof args?.repo === 'string' && args.repo.trim().startsWith('@')) {\n    throw new Error('Group routing is not available in GitNexus MCP read-only mode.');\n  }\n  // crossDepth/subgroup only do anything on the @group path rejected above,\n  // but rejecting them here keeps the advertised schema and the dispatch\n  // contract in agreement.\n  for (const groupOnlyArg of ['crossDepth', 'subgroup']) {","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/abhigyanpatwari/GitNexus/blob/aac7515d2a8c50a1f8f923c6fb77218b333560d6/gitnexus/src/mcp/read-only-policy.ts#L9-L45","documentation":"Thrown by resolveMcpReadOnlyMode when the GITNEXUS_MCP_READ_ONLY environment variable is set to anything other than the exact recognized values. After trimming, only undefined (unset), '' (empty), '0' (read-write) and '1' (read-only) are accepted. The check is strict because this variable turns the MCP server into a hardened read-only surface, so loose truthiness parsing ('true', 'yes', 'on') is intentionally rejected.","triggerScenarios":"Starting the GitNexus MCP server with GITNEXUS_MCP_READ_ONLY set to 'true', 'yes', 'on', '2', 'TRUE', 'read', or any other string; the error surfaces as soon as the policy is resolved at startup or on first tool/resource dispatch.","commonSituations":"Operators habitually write GITNEXUS_MCP_READ_ONLY=true (shell/COMMON convention) instead of 1. A .env loader keeps a quoted or padded value. Upgrading from a version that ignored the variable to one that enforces it.","solutions":["Set the variable to exactly 1 (enable read-only) or 0 (disable), e.g. GITNEXUS_MCP_READ_ONLY=1 npx gitnexus mcp.","Unset the variable entirely if you want read-write mode — undefined and empty both mean off.","Search the environment and .env files for the variable and correct every occurrence; do not use true/false/yes/no spellings."],"exampleFix":"# before\nexport GITNEXUS_MCP_READ_ONLY=true\n\n# after\nexport GITNEXUS_MCP_READ_ONLY=1","handlingStrategy":"validation","validationCode":"const raw = process.env.GITNEXUS_MCP_READ_ONLY;\nconst readOnly = raw === undefined || raw.trim() === '' || raw.trim() === '0' ? false : raw.trim() === '1';\nif (readOnly === undefined && !(raw!.trim() === '1')) {\n  throw new Error(`GITNEXUS_MCP_READ_ONLY has invalid value: ${JSON.stringify(raw)}`);\n}","typeGuard":"const isValidReadOnlyEnv = (v: string | undefined): boolean =>\n  v === undefined || ['', '0', '1'].includes(v.trim());","tryCatchPattern":"try {\n  spawnGitnexusMcp();\n} catch (e) {\n  if (e instanceof Error && e.message.includes('GITNEXUS_MCP_READ_ONLY')) {\n    // config error: fix the env value and restart; retrying unchanged cannot help\n  }\n  throw e;\n}","preventionTips":["Standardize on 0/1 spellings in all .env files and deployment manifests; lint for =true/=yes.","Add a startup env validation step to deployment scripts before launching the MCP server.","Document the variable as boolean-flag style (0/1) wherever it is referenced."],"tags":["mcp","read-only-mode","environment-variables","validation","configuration"],"backgroundTag":"invalid-env-var-value","analyzedSha":"aac7515d2a8c50a1f8f923c6fb77218b333560d6","analyzedAt":"2026-08-20T23:29:22.980Z","contentChangedAt":"2026-08-20T23:29:22.980Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}