{"record":{"id":"842c1abf3f8a85ff","repo":"ruvnet/ruflo","slug":"header-not-found-in-codex-config","errorCode":null,"errorMessage":"${header} not found in Codex config","messagePattern":"(.+?) not found in Codex config","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/codex/src/mcp-config.ts","lineNumber":142,"sourceCode":"}\n\nexport function hasExpectedRufloMcpTimeout(registration: CodexMcpRegistration): boolean {\n  return typeof registration.startup_timeout_sec === 'number'\n    && registration.startup_timeout_sec >= RUFLO_MCP_STARTUP_TIMEOUT_SEC;\n}\n\nexport function upsertMcpServerStartupTimeout(\n  config: string,\n  serverName = RUFLO_MCP_SERVER_NAME,\n  timeoutSec = RUFLO_MCP_STARTUP_TIMEOUT_SEC,\n): string {\n  const eol = config.includes('\\r\\n') ? '\\r\\n' : '\\n';\n  const lines = config.split(/\\r?\\n/);\n  const header = `[mcp_servers.${serverName}]`;\n  const start = lines.findIndex(line => line.trim() === header);\n\n  if (start < 0) {\n    throw new Error(`${header} not found in Codex config`);\n  }\n\n  let end = lines.length;\n  for (let index = start + 1; index < lines.length; index += 1) {\n    if (lines[index]?.trim().startsWith('[')) {\n      end = index;\n      break;\n    }\n  }\n\n  const timeoutPattern = /^\\s*startup_timeout_sec\\s*=/;\n  for (let index = start + 1; index < end; index += 1) {\n    const line = lines[index] ?? '';\n    if (timeoutPattern.test(line)) {\n      const parsed = line.match(/^(\\s*startup_timeout_sec\\s*=\\s*)([0-9][0-9_]*)(.*)$/);\n      const currentValue = parsed ? Number(parsed[2]!.replace(/_/g, '')) : Number.NaN;\n      if (Number.isFinite(currentValue) && currentValue >= timeoutSec) {\n        return config;","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/codex/src/mcp-config.ts#L124-L160","documentation":"upsertMcpServerStartupTimeout() performs a surgical text edit of the Codex config.toml: it locates the literal header line `[mcp_servers.ruflo]` (trim-matched) and rewrites the section body. If the section does not exist, the function refuses to invent it and throws '<header> not found in Codex config' — it is an editor for an existing section, not a creator.","triggerScenarios":"Calling upsertMcpServerStartupTimeout on a fresh ~/.codex/config.toml that has no [mcp_servers.ruflo] section; the server was registered under a different name (serverName mismatch); manual edits removed or renamed the header; CRLF/BOM formatting shifted the line so trim() still matches only if truly present.","commonSituations":"Setup steps run out of order (timeout upsert before `codex mcp add` created the section); users renamed the MCP server; config regenerated from scratch by another tool.","solutions":["Register the server first (e.g. `codex mcp add ruflo -- npx ruflo mcp start` or the project's setup command) so the section exists, then call the upsert","Or append the section manually to ~/.codex/config.toml before calling","Pass the matching serverName if the server was registered under a different key"],"exampleFix":"# before: ~/.codex/config.toml has no ruflo section\n# after: add it, then re-run\n[mcp_servers.ruflo]\ncommand = \"npx\"\nargs = [\"ruflo\", \"mcp\", \"start\"]\nstartup_timeout_sec = 120","handlingStrategy":"validation","validationCode":"function hasSection(config: string, serverName: string): boolean {\n  return config.split(/\\r?\\n/).some(l => l.trim() === `[mcp_servers.${serverName}]`);\n}","typeGuard":null,"tryCatchPattern":"let cfg = readConfig();\nif (!hasSection(cfg, 'ruflo')) cfg += '\\n[mcp_servers.ruflo]\\ncommand = \"npx\"\\nargs = [\"ruflo\", \"mcp\", \"start\"]\\n';\nwriteConfig(cfg);\ncfg = upsertMcpServerStartupTimeout(cfg);","preventionTips":["Run registration/setup before any config-patching step; order matters","Key edits by the same serverName used at registration","Keep backups of config.toml before programmatic edits"],"tags":["config","toml","mcp","setup-order"],"backgroundTag":"missing-config-section","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}