fix(mcp): name raw argument bytes when brain_edit refuses an empty old_str

hyperguild#115: a session reported "old_str is empty" with old_str that
was never empty on their end. Server-side round-trip re-verified clean
(fresh brain_edit call, real content, succeeds) — the code path itself
isn't broken, but its error left no way to tell "client sent empty" apart
from "something between the client and here lost the field" without a
second investigation. The refusal now names the raw argument byte count.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-22 23:18:43 +02:00
co-authored by Claude Sonnet 5
parent cc86a74dc5
commit 1e57f49595
2 changed files with 31 additions and 0 deletions
+8
View File
@@ -3,6 +3,7 @@ package mcp
import (
"context"
"encoding/json"
"errors"
"fmt"
"log/slog"
"strings"
@@ -180,6 +181,13 @@ func (s *Server) editWithScope(args json.RawMessage, scope notes.Scope) (notes.R
}
res, err := notes.Edit(s.brainDir, a.Path, a.OldStr, a.NewStr, scope)
if err != nil {
if errors.Is(err, notes.ErrDegenerate) && a.OldStr == "" {
// hyperguild#115: "old_str is empty" alone doesn't say whether the
// caller sent it empty or a hop between the caller and here lost
// it. Naming the raw argument byte count makes that distinguishable
// without a second investigation.
return notes.Result{}, nil, fmt.Errorf("%w (raw arguments were %d bytes)", err, len(args))
}
return notes.Result{}, nil, err
}