📝 Bug Description
From a working directory that holds several git repos (so project detection returns ambiguous), mem_get_observation always returns ambiguous_project, even for an ID that exists. The tool has no project argument, so there is no way to satisfy it from the call.
mem_search and mem_context work from the same directory because they accept project. The result is that an agent can see a 300-char preview of a memory but can never read the full content.
mem_update has the same shape. It resolves a write project before loading the observation (resolveWriteProjectWithProcessOverride, around L1689 in internal/mcp/mcp.go) and fails from an ambiguous directory, even though the target is fully identified by id. Its project argument is the new value to set, not a resolution override.
🔄 Steps to Reproduce
- Open a Claude Code session in a directory that contains more than one git repo and no
.engram/config.json.
mem_search(project: "some-project", query: "...") returns a preview with #1406.
mem_get_observation(id: 1406) returns ambiguous_project.
✅ Expected Behavior
The observation is returned. The ID already identifies the record, and the observation carries its own Project.
❌ Actual Behavior
{"error_code":"ambiguous_project","message":"Cannot determine project: ambiguous project: multiple git repos found in cwd", ...}
GET /observations/1406 on the local HTTP server returns the full observation from the same machine, so the data is there.
Operating System
Windows
Engram Version
2.2.1 (Claude Code plugin 0.1.3)
Agent / Client
Claude Code
📋 Relevant Logs
💡 Additional Context
Cause. handleGetObservation in internal/mcp/mcp.go (v2.2.1, around L2240) loads the observation first and only then resolves the project, for the response envelope:
obs, err := s.GetObservation(id) // succeeds
...
detRes, detErr := resolveReadProjectWithProcessOverride(s, "", cfg.DefaultProject)
...
if detErr != nil {
return readProjectErrorResult(activity, detRes, detErr), nil // discards obs
}
The comment there says "No per-call override is possible for get-by-ID". The lookup does not depend on the project. The ambiguity only affects the envelope, but it discards a result that was already found.
Suggested fix. Either of these would solve it:
- On a detection error, answer with the observation anyway and use
obs.Project for the envelope.
- Accept an optional
project argument, as mem_search does, and use it as the override.
Why the directory is ambiguous. We keep the root ambiguous on purpose, as a guard rail, so that no save lands in a guessed project. Every write passes project explicitly. The read-by-ID path is the only one left with no way to comply.
📝 Bug Description
From a working directory that holds several git repos (so project detection returns
ambiguous),mem_get_observationalways returnsambiguous_project, even for an ID that exists. The tool has noprojectargument, so there is no way to satisfy it from the call.mem_searchandmem_contextwork from the same directory because they acceptproject. The result is that an agent can see a 300-char preview of a memory but can never read the full content.mem_updatehas the same shape. It resolves a write project before loading the observation (resolveWriteProjectWithProcessOverride, around L1689 ininternal/mcp/mcp.go) and fails from an ambiguous directory, even though the target is fully identified byid. Itsprojectargument is the new value to set, not a resolution override.🔄 Steps to Reproduce
.engram/config.json.mem_search(project: "some-project", query: "...")returns a preview with#1406.mem_get_observation(id: 1406)returnsambiguous_project.✅ Expected Behavior
The observation is returned. The ID already identifies the record, and the observation carries its own
Project.❌ Actual Behavior
{"error_code":"ambiguous_project","message":"Cannot determine project: ambiguous project: multiple git repos found in cwd", ...}GET /observations/1406on the local HTTP server returns the full observation from the same machine, so the data is there.Operating System
Windows
Engram Version
2.2.1 (Claude Code plugin 0.1.3)
Agent / Client
Claude Code
📋 Relevant Logs
💡 Additional Context
Cause.
handleGetObservationininternal/mcp/mcp.go(v2.2.1, around L2240) loads the observation first and only then resolves the project, for the response envelope:The comment there says "No per-call override is possible for get-by-ID". The lookup does not depend on the project. The ambiguity only affects the envelope, but it discards a result that was already found.
Suggested fix. Either of these would solve it:
obs.Projectfor the envelope.projectargument, asmem_searchdoes, and use it as the override.Why the directory is ambiguous. We keep the root ambiguous on purpose, as a guard rail, so that no save lands in a guessed project. Every write passes
projectexplicitly. The read-by-ID path is the only one left with no way to comply.