thedotmack/claude-mem · error

Found mcpServers/claude-mem markers but could not locate a…

Error message

Found mcpServers/claude-mem markers but could not locate a replaceable claude-mem block

What it means

mergeGooseYamlConfig() updates an existing claude-mem MCP entry in a Goose YAML config. It detects that the file already mentions mcpServers/claude-mem, then tries to match the whole two-space-indented 'claude-mem:' block with a regex so it can replace it. If the file contains claude-mem markers but the regex cannot match a well-formed block (malformed or unusually formatted YAML), it throws rather than corrupting the config with a partial replacement.

Solutions

  1. Open the goose config.yaml and reformat the claude-mem entry to the standard two-space top-level layout under mcpServers:, then rerun the installer.
  2. Back up and simplify: move the claude-mem block out (or reset the file to a minimal mcpServers: config) so the installer can insert a clean entry.
  3. Let the installer rewrite the entry by removing the stale claude-mem markers manually and rerunning installGooseMcpIntegration.

Example fix

// before: malformed indentation prevents block match
mcpServers:
    claude-mem:
        command: old-command

// after: standard two-space block the regex can replace
mcpServers:
  claude-mem:
    command: bun
    args:
      - /path/to/mcp-server.cjs
Defensive patterns

Strategy: try-catch

Validate before calling

import { readFileSync } from 'fs';
const yaml = readFileSync(gooseConfigPath, 'utf8');
if (/claude-mem/.test(yaml) && !/( {2}claude-mem:\n(?:.*\n)*?(?= {2}\S|\n\n|^\S|$))/m.test(yaml)) {
  console.error('Goose config has claude-mem markers but a non-standard block; reformat to two-space indentation first');
}

Try / catch

try {
  installGooseMcpIntegration(configPath, mcpServerPath);
} catch (err) {
  if (err instanceof Error && err.message.includes('could not locate a replaceable claude-mem block')) {
    // back up config.yaml, reformat the claude-mem entry to standard two-space YAML, rerun
  } else throw err;
}

Prevention

When it happens

Trigger: installGooseMcpIntegration() -> mergeGooseYamlConfig() runs against a ~/.config/goose/config.yaml where gooseConfigHasClaudeMemEntry() returns true (claude-mem/mcpServers markers present) but the regex /( {2}claude-mem:\n(?:.*\n)*?(?= {2}\S|\n\n|^\S|$))/m does not match — e.g. 'claude-mem:' is indented differently, nested deeper, or the block layout deviates from the expected two-space format.

Common situations: A hand-edited or tool-reformatted config.yaml with non-standard indentation (tabs, four spaces); claude-mem nested under a different parent key; comments or blank-line patterns between entries breaking the block matcher; a config written by a different Goose version with a different schema.

Related errors


AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17). Data as JSON: /api/errors/3aec6c17621967ef. Report an issue: GitHub.

Appendix: source

Thrown at src/services/integrations/McpIntegrations.ts:192

    mergeGooseYamlConfig(configPath, mcpServerPath);
    return 0;
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    console.error(`\nInstallation failed: ${message}`);
    return 1;
  }
}

function mergeGooseYamlConfig(configPath: string, mcpServerPath: string): void {
  if (existsSync(configPath)) {
    let yamlContent = readFileSync(configPath, 'utf-8');

    if (gooseConfigHasClaudeMemEntry(yamlContent)) {
      const claudeMemPattern = /( {2}claude-mem:\n(?:.*\n)*?(?= {2}\S|\n\n|^\S|$))/m;
      const newEntry = buildGooseClaudeMemEntryYaml(mcpServerPath) + '\n';

      if (!claudeMemPattern.test(yamlContent)) {
        throw new Error('Found mcpServers/claude-mem markers but could not locate a replaceable claude-mem block');
      }
      yamlContent = yamlContent.replace(claudeMemPattern, newEntry);
      writeFileSync(configPath, yamlContent);
      console.log(`  Updated existing claude-mem entry in: ${configPath}`);
    } else if (yamlContent.includes('mcpServers:')) {
      const mcpServersIndex = yamlContent.indexOf('mcpServers:');
      const insertionPoint = mcpServersIndex + 'mcpServers:'.length;
      const newEntry = '\n' + buildGooseClaudeMemEntryYaml(mcpServerPath);

      yamlContent =
        yamlContent.slice(0, insertionPoint) +
        newEntry +
        yamlContent.slice(insertionPoint);

      writeFileSync(configPath, yamlContent);
      console.log(`  Added claude-mem to existing mcpServers in: ${configPath}`);
    } else {
      const mcpBlock = '\n' + buildGooseClaudeMemEntryYaml(mcpServerPath, true) + '\n';

View on GitHub (pinned to d8bc9755e7)