Skip to content

fix(tools): handle the memory tool commands Claude actually sends - #1597

Open
Rikinshah787 wants to merge 1 commit into
supermemoryai:mainfrom
Rikinshah787:fix/claude-memory-wire-format
Open

fix(tools): handle the memory tool commands Claude actually sends#1597
Rikinshah787 wants to merge 1 commit into
supermemoryai:mainfrom
Rikinshah787:fix/claude-memory-wire-format

Conversation

@Rikinshah787

Copy link
Copy Markdown

Read ClaudeMemoryTool against Anthropic's memory tool docs (https://platform.claude.com/docs/en/agents-and-tools/tool-use/memory-tool) and found three places where the handler doesn't match what the model actually sends.

The big one is rename: Claude sends old_path/new_path, no path at all. handleCommand validates command.path first, so every rename coming from a real model fails with "Cannot read properties of undefined (reading 'startsWith')". The existing tests only exercise a path + new_path shape, which is why they pass.

The other two:

  • insert_line is documented as "insert after this line", with 0 meaning the top of the file and n_lines appending. The code spliced at insertLine - 1 and rejected 0, so every insert landed one line above where Claude asked, the top of the file was unreachable, and the success message gave the model no hint anything shifted. This one quietly corrupts memory files over repeated edits.
  • str_replace with new_str omitted is how the model deletes text; we returned an error for it.

Changes: rename resolves its source from old_path ?? path so anyone calling with the old shape keeps working, insert validates [0, n_lines] and splices at insert_line, missing new_str defaults to "". The rename example in the docs page showed the same path shape the code expected, fixed that too.

Tests: added test/claude-memory-commands.test.ts with the supermemory client mocked so it runs without an API key. 8 pass on this branch; 7 of 8 fail on main (the passing one is the backwards-compat case). Left the existing integration tests alone since they need a live key and currently don't typecheck anyway (#1545).

Not related to #1547 / #1586 - those are about customId normalization, this is about the command shapes themselves.

Three places where ClaudeMemoryTool diverges from the documented
memory_20250818 wire format:

- rename sends old_path/new_path, not path. handleCommand validated
  command.path, so every rename coming from a real model died with
  "Cannot read properties of undefined (reading 'startsWith')".
  path is still accepted as the source for existing callers.
- insert_line means "insert after this line" (0 = top of file), but we
  spliced at insertLine - 1 and rejected 0, so every insert landed one
  line above where Claude asked and inserting at the top was impossible.
- str_replace with new_str omitted is a deletion per the spec; we
  rejected it.

The new tests mock the supermemory client so they run without an API
key. Also fixed the rename example in the docs, which showed the same
path shape the code expected.
Copilot AI lite review requested due to automatic review settings August 25, 2026 23:08

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants