From bdaff31117b15863e610763acf3a0b742d669d58 Mon Sep 17 00:00:00 2001 From: fury Date: Mon, 5 Jan 2026 00:12:35 -0800 Subject: [PATCH] fix: Return error when all mailbox queries fail in listFromDir MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, listFromDir silently ignored all query errors and returned an empty list with no error if all queries failed. This could hide real problems like a corrupted beads database or missing bd command. Now the function tracks whether at least one query succeeded. If all queries fail, it returns the last error wrapped with context. This enables graceful degradation (partial results if some queries work) while surfacing complete failures. (gt-lm41t) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- internal/mail/mailbox.go | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/internal/mail/mailbox.go b/internal/mail/mailbox.go index 31dd7463..ad69a356 100644 --- a/internal/mail/mailbox.go +++ b/internal/mail/mailbox.go @@ -112,9 +112,12 @@ func (m *Mailbox) listBeads() ([]*Message, error) { // listFromDir queries messages from a beads directory. // Returns messages where identity is the assignee OR a CC recipient. // Includes both open and hooked messages (hooked = auto-assigned handoff mail). -func (m *Mailbox) listFromDir(beadsDir string) ([]*Message, error) { //nolint:unparam // error return kept for future use +// If all queries fail, returns the last error encountered. +func (m *Mailbox) listFromDir(beadsDir string) ([]*Message, error) { seen := make(map[string]bool) var messages []*Message + var lastErr error + anySucceeded := false // Get all identity variants to query (handles legacy vs normalized formats) identities := m.identityVariants() @@ -123,7 +126,10 @@ func (m *Mailbox) listFromDir(beadsDir string) ([]*Message, error) { //nolint:un for _, identity := range identities { for _, status := range []string{"open", "hooked"} { msgs, err := m.queryMessages(beadsDir, "--assignee", identity, status) - if err == nil { + if err != nil { + lastErr = err + } else { + anySucceeded = true for _, msg := range msgs { if !seen[msg.ID] { seen[msg.ID] = true @@ -137,7 +143,10 @@ func (m *Mailbox) listFromDir(beadsDir string) ([]*Message, error) { //nolint:un // Query for CC'd messages (open only) for _, identity := range identities { ccMsgs, err := m.queryMessages(beadsDir, "--label", "cc:"+identity, "open") - if err == nil { + if err != nil { + lastErr = err + } else { + anySucceeded = true for _, msg := range ccMsgs { if !seen[msg.ID] { seen[msg.ID] = true @@ -147,6 +156,11 @@ func (m *Mailbox) listFromDir(beadsDir string) ([]*Message, error) { //nolint:un } } + // If ALL queries failed, return the last error + if !anySucceeded && lastErr != nil { + return nil, fmt.Errorf("all mailbox queries failed: %w", lastErr) + } + return messages, nil }