{"record":{"id":"3aec6c17621967ef","repo":"thedotmack/claude-mem","slug":"found-mcpservers-claude-mem-markers-but-could-not","errorCode":null,"errorMessage":"Found mcpServers/claude-mem markers but could not locate a replaceable claude-mem block","messagePattern":"Found mcpServers/claude-mem markers but could not locate a replaceable claude-mem block","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/services/integrations/McpIntegrations.ts","lineNumber":192,"sourceCode":"    mergeGooseYamlConfig(configPath, mcpServerPath);\n    return 0;\n  } catch (error) {\n    const message = error instanceof Error ? error.message : String(error);\n    console.error(`\\nInstallation failed: ${message}`);\n    return 1;\n  }\n}\n\nfunction mergeGooseYamlConfig(configPath: string, mcpServerPath: string): void {\n  if (existsSync(configPath)) {\n    let yamlContent = readFileSync(configPath, 'utf-8');\n\n    if (gooseConfigHasClaudeMemEntry(yamlContent)) {\n      const claudeMemPattern = /( {2}claude-mem:\\n(?:.*\\n)*?(?= {2}\\S|\\n\\n|^\\S|$))/m;\n      const newEntry = buildGooseClaudeMemEntryYaml(mcpServerPath) + '\\n';\n\n      if (!claudeMemPattern.test(yamlContent)) {\n        throw new Error('Found mcpServers/claude-mem markers but could not locate a replaceable claude-mem block');\n      }\n      yamlContent = yamlContent.replace(claudeMemPattern, newEntry);\n      writeFileSync(configPath, yamlContent);\n      console.log(`  Updated existing claude-mem entry in: ${configPath}`);\n    } else if (yamlContent.includes('mcpServers:')) {\n      const mcpServersIndex = yamlContent.indexOf('mcpServers:');\n      const insertionPoint = mcpServersIndex + 'mcpServers:'.length;\n      const newEntry = '\\n' + buildGooseClaudeMemEntryYaml(mcpServerPath);\n\n      yamlContent =\n        yamlContent.slice(0, insertionPoint) +\n        newEntry +\n        yamlContent.slice(insertionPoint);\n\n      writeFileSync(configPath, yamlContent);\n      console.log(`  Added claude-mem to existing mcpServers in: ${configPath}`);\n    } else {\n      const mcpBlock = '\\n' + buildGooseClaudeMemEntryYaml(mcpServerPath, true) + '\\n';","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d768ba364302d12b76e69e4f021f0bb1d2d50ed6/src/services/integrations/McpIntegrations.ts#L174-L210","documentation":"mergeGooseYamlConfig() updates an existing Goose config (~/.config/goose/config.yaml). When gooseConfigHasClaudeMemEntry() detects both an 'mcpServers:' line and a 'claude-mem:' line, it tries to replace the existing claude-mem block via a regex expecting exactly two-space indentation. If that regex does not match (the block uses different indentation or structure), it throws rather than risk a corrupting partial rewrite.","triggerScenarios":"The Goose config already contains mcpServers and a claude-mem entry but they are indented/structured in a way the rigid two-space regex `/( {2}claude-mem:\\n(?:.*\\n)*?(?= {2}\\S|\\n\\n|^\\S|$))/m` cannot match — e.g. four-space indent, tabs, the claude-mem key at top level, or a different nesting under mcpServers.","commonSituations":"User hand-edited config.yaml with non-standard indentation; another tool wrote the config with tabs or four spaces; the claude-mem block was split across mcpServers in an unusual layout; a previous merge left a malformed block.","solutions":["Open ~/.config/goose/config.yaml and normalize the existing claude-mem block to two-space indentation under mcpServers so the installer can replace it.","Alternatively, delete the existing claude-mem entry from the YAML entirely so the installer adds a fresh one under mcpServers.","Re-run installGooseMcpIntegration once the block is removable or correctly indented."],"exampleFix":"# before — four-space indent, regex won't match\nmcpServers:\n    claude-mem:\n        command: node\n\n# after — two-space indent\nmcpServers:\n  claude-mem:\n    command: node\n# re-run: npx claude-mem@latest install --goose","handlingStrategy":"validation","validationCode":"// Pre-check: is the existing claude-mem block replaceable by the installer's regex?\nfunction gooseBlockReplaceable(yaml: string): boolean {\n  const hasMarkers = yaml.includes('claude-mem:') && yaml.includes('mcpServers:');\n  if (!hasMarkers) return true; // nothing to replace\n  return /( {2}claude-mem:\\n(?:.*\\n)*?(?= {2}\\S|\\n\\n|^\\S|$))/m.test(yaml);\n}","typeGuard":"function isGooseBlockUnreplaceable(e: unknown): boolean {\n  return e instanceof Error && /could not locate a replaceable claude-mem block/i.test(e.message);\n}","tryCatchPattern":"try {\n  mergeGooseYamlConfig(configPath, mcpServerPath);\n} catch (e) {\n  if (e instanceof Error && /could not locate a replaceable claude-mem block/i.test(e.message)) {\n    console.error(`Edit ${configPath}: use 2-space indent or remove the claude-mem entry, then re-run.`);\n    process.exit(1);\n  }\n  throw e;\n}","preventionTips":["Keep Goose config at standard 2-space YAML indentation under mcpServers.","Avoid tabs in YAML configs.","If hand-editing, delete the old claude-mem entry entirely so the installer adds a fresh one."],"tags":["goose","yaml","config","installer","mcp"],"backgroundTag":null,"analyzedSha":"d768ba364302d12b76e69e4f021f0bb1d2d50ed6","analyzedAt":"2026-08-12T23:52:55.241Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}