thedotmack/claude-mem · error · Error

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

Error message

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

What it means

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.

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 d768ba3643)

Solutions

  1. Open ~/.config/goose/config.yaml and normalize the existing claude-mem block to two-space indentation under mcpServers so the installer can replace it.
  2. Alternatively, delete the existing claude-mem entry from the YAML entirely so the installer adds a fresh one under mcpServers.
  3. Re-run installGooseMcpIntegration once the block is removable or correctly indented.

Example fix

# before — four-space indent, regex won't match
mcpServers:
    claude-mem:
        command: node

# after — two-space indent
mcpServers:
  claude-mem:
    command: node
# re-run: npx claude-mem@latest install --goose
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check: is the existing claude-mem block replaceable by the installer's regex?
function gooseBlockReplaceable(yaml: string): boolean {
  const hasMarkers = yaml.includes('claude-mem:') && yaml.includes('mcpServers:');
  if (!hasMarkers) return true; // nothing to replace
  return /( {2}claude-mem:\n(?:.*\n)*?(?= {2}\S|\n\n|^\S|$))/m.test(yaml);
}

Type guard

function isGooseBlockUnreplaceable(e: unknown): boolean {
  return e instanceof Error && /could not locate a replaceable claude-mem block/i.test(e.message);
}

Try / catch

try {
  mergeGooseYamlConfig(configPath, mcpServerPath);
} catch (e) {
  if (e instanceof Error && /could not locate a replaceable claude-mem block/i.test(e.message)) {
    console.error(`Edit ${configPath}: use 2-space indent or remove the claude-mem entry, then re-run.`);
    process.exit(1);
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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