From d71c5152ca7e0d44294f95739d88de9431052cbe Mon Sep 17 00:00:00 2001 From: Tye Date: Thu, 18 Jun 2026 15:58:15 -0700 Subject: [PATCH] fix(server): surface partial results in list-all-entities instead of masking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The list-across-all-entities path silently `continue`d on a per-entity List error, so a failing entity produced a 200 with quietly-incomplete results. Log each skip and a partial-result summary so the gap is visible (behavior otherwise unchanged — one bad entity still doesn't fail the whole request). go build ./... + go vet + go test ./cmd/keyoku-server/ all green. Co-Authored-By: Claude Opus 4.8 (1M context) --- cmd/keyoku-server/handlers_memory.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cmd/keyoku-server/handlers_memory.go b/cmd/keyoku-server/handlers_memory.go index 40ef2a8..1a2d014 100644 --- a/cmd/keyoku-server/handlers_memory.go +++ b/cmd/keyoku-server/handlers_memory.go @@ -5,6 +5,7 @@ package main import ( "fmt" + "log" "net/http" "sort" "strings" @@ -209,13 +210,21 @@ func (h *Handlers) HandleListMemories(w http.ResponseWriter, r *http.Request) { return } var allMemories []memoryJSON + skipped := 0 for _, eid := range entities { memories, err := h.k.List(r.Context(), eid, limit) if err != nil { + // Don't fail the whole request for one bad entity — but don't hide + // it either: a silent skip makes a partial 200 look complete. + log.Printf("WARN: list memories for entity %q failed, skipping: %v", eid, err) + skipped++ continue } allMemories = append(allMemories, toMemoryJSONSlice(memories)...) } + if skipped > 0 { + log.Printf("WARN: list-all-entities returned partial results: %d of %d entities skipped", skipped, len(entities)) + } // Sort by created_at descending, then cap to limit sort.Slice(allMemories, func(i, j int) bool { return allMemories[i].CreatedAt.After(allMemories[j].CreatedAt)