{"record":{"id":"6f6e385999eb061c","repo":"JuliusBrussee/caveman","slug":"existing-gemini-caveman-routing-block-is-corrupted","errorCode":null,"errorMessage":"existing Gemini Caveman routing block is corrupted; run `caveman doctor gemini`","messagePattern":"existing Gemini Caveman routing block is corrupted; run `caveman doctor gemini`","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/cli/src/index.ts","lineNumber":6089,"sourceCode":"      kind: \"claude-settings\",\n      owned: { route, previous_route: previousRoute ?? null },\n    },\n    {\n      file: mcpPath,\n      before: mcpBefore,\n      after: Buffer.from(JSON.stringify(mcpRoot, null, 2) + \"\\n\"),\n      kind: \"claude-mcp\",\n      owned: { installed_mcp: installedMcp, previous_mcp: previousMcp ?? null },\n    },\n  ];\n}\n\nfunction geminiNativeEnv(source: string, route: string): { text: string; block: string } {\n  let stripped = source;\n  const start = stripped.indexOf(GEMINI_NATIVE_ENV_BEGIN);\n  const finish = stripped.indexOf(GEMINI_NATIVE_ENV_END);\n  if ((start === -1) !== (finish === -1) || (start !== -1 && finish < start)) {\n    throw new Error(\"existing Gemini Caveman routing block is corrupted; run `caveman doctor gemini`\");\n  }\n  if (start !== -1) stripped = `${stripped.slice(0, start)}${stripped.slice(finish + GEMINI_NATIVE_ENV_END.length)}`.trim();\n  const block = [\n    GEMINI_NATIVE_ENV_BEGIN,\n    `GEMINI_BASE_URL=${route}`,\n    `GOOGLE_GEMINI_BASE_URL=${route}`,\n    `GOOGLE_VERTEX_BASE_URL=${appendUrlPath(route, \"/vertex\")}`,\n    GEMINI_NATIVE_ENV_END,\n  ].join(\"\\n\");\n  return { text: `${stripped}${stripped ? \"\\n\\n\" : \"\"}${block}\\n`, block };\n}\n\nfunction geminiNativeMutations(gw: string, mcpBinary: string): NativeMutation[] {\n  if (wrapMode(gw) === \"managed\") {\n    throw new Error(\"managed Gemini CLI routing is unsupported because Gemini CLI cannot send separate Caveman and upstream credentials\");\n  }\n  const settingsPath = geminiSettingsPath();\n  const settingsBefore = fileBytes(settingsPath);","sourceCodeStart":6071,"sourceCodeEnd":6107,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/cli/src/index.ts#L6071-L6107","documentation":"geminiNativeEnv() strips and rewrites the managed routing block in ~/.gemini/.env delimited by GEMINI_NATIVE_ENV_BEGIN/GEMINI_NATIVE_ENV_END markers. It throws when exactly one marker is missing (XOR) or END appears before BEGIN — i.e. the managed block was partially deleted or reordered, so idempotent re-stamping is unsafe.","triggerScenarios":"Enabling/re-enabling native Gemini routing when ~/.gemini/.env contains GEMINI_NATIVE_ENV_BEGIN without its END (or vice versa), or the END marker appears earlier in the file than BEGIN.","commonSituations":"User manually deleted part of the Caveman block while tidying the env file; a merge conflict or editor truncation; earlier uninstall removed only one marker.","solutions":["Run `caveman doctor gemini` to repair or remove the corrupted block","Manually open ~/.gemini/.env and delete the orphaned GEMINI_NATIVE_ENV marker line(s) so neither remains, then retry the install","If unsure which lines are Caveman-owned, remove everything between (and including) both marker styles and let the next install re-stamp cleanly"],"exampleFix":"# before — ~/.gemini/.env\n>>> CAVEMAN NATIVE ENV BEGIN >>>\nGEMINI_BASE_URL=http://127.0.0.1:8080/w/gemini\n# (END marker was deleted by hand)\n\n# after — marker lines fully removed, then re-run install to re-stamp\nGEMINI_BASE_URL=http://127.0.0.1:8080/w/gemini","handlingStrategy":"validation","validationCode":"import { readFileSync } from \"node:fs\";\nfunction geminiEnvMarkersBalanced(path: string): boolean {\n  let src: string;\n  try { src = readFileSync(path, \"utf8\"); } catch { return true; }\n  const b = src.indexOf(GEMINI_NATIVE_ENV_BEGIN);\n  const e = src.indexOf(GEMINI_NATIVE_ENV_END);\n  return (b === -1) === (e === -1) && (b === -1 || e > b);\n}","typeGuard":null,"tryCatchPattern":"try { nativeInstallGemini(); } catch (e) {\n  if (e instanceof Error && /Gemini Caveman routing block is corrupted/.test(e.message)) {\n    spawnSync(\"caveman\", [\"doctor\", \"gemini\"], { stdio: \"inherit\" });\n    nativeInstallGemini();\n  } else throw e;\n}","preventionTips":["Edit ~/.gemini/.env with whole-block operations: delete BEGIN through END together or not at all","Run `caveman doctor gemini` after manual edits to Caveman-managed files","Keep managed marker lines untouched when tidying env files"],"tags":["config","gemini","markers","corruption","env-file"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}