Fix widespread double JSON encoding bug in daemon RPC calls (bd-1048, bd-4ec8)

Multiple CLI commands had a systematic bug where ResolveID responses were
incorrectly converted using string(resp.Data) instead of json.Unmarshal.
Since resp.Data is json.RawMessage (already JSON-encoded), this preserved
the JSON quotes, causing IDs to become "bd-1048" instead of bd-1048.
When re-marshaled for subsequent RPC calls, these became double-quoted
("\"bd-1048\""), causing database lookups to fail.

Bugs fixed:
1. Nil pointer dereference in handleShow - added nil check after GetIssue
2. Double JSON encoding in 12 locations across 4 commands:
   - bd show (3 instances in show.go)
   - bd dep add/remove/tree (5 instances in dep.go)
   - bd label add/remove/list (3 instances in label.go)
   - bd reopen (1 instance in reopen.go)

All instances replaced string(resp.Data) with proper json.Unmarshal.
Removed debug logging added during investigation.

Tested: All affected commands now work correctly with daemon mode.
This commit is contained in:
Steve Yegge
2025-11-02 22:34:24 -08:00
parent 63ff9b93bc
commit 481649a605
9 changed files with 67 additions and 37 deletions

View File

@@ -191,10 +191,8 @@ func (s *Server) checkAndAutoImportIfStale(req *Request) error {
// If import is already running, skip and let the request proceed (bd-8931)
// This prevents blocking RPC requests when import is in progress
if !s.importInProgress.CompareAndSwap(false, true) {
fmt.Fprintf(os.Stderr, "Debug: auto-import already in progress, skipping (bd-1048)\n")
return nil
}
fmt.Fprintf(os.Stderr, "Debug: acquired import lock, proceeding with auto-import (bd-1048)\n")
// Track whether we should release the lock via defer
// Set to false if we manually release early to avoid double-release bug
@@ -215,23 +213,16 @@ func (s *Server) checkAndAutoImportIfStale(req *Request) error {
s.importInProgress.Store(false)
shouldDeferRelease = false
if os.Getenv("BD_DEBUG") != "" {
fmt.Fprintf(os.Stderr, "Debug: skipping auto-import, .beads files have uncommitted changes\n")
}
fmt.Fprintf(os.Stderr, "Warning: auto-import skipped - .beads files have uncommitted changes. Run 'bd import' manually after committing.\n")
return nil
}
// Double-check staleness after acquiring lock (another goroutine may have imported)
fmt.Fprintf(os.Stderr, "Debug: checking staleness after lock acquisition (bd-1048)\n")
isStale, err = autoimport.CheckStaleness(ctx, store, dbPath)
if err != nil || !isStale {
fmt.Fprintf(os.Stderr, "Debug: staleness check returned: stale=%v err=%v (bd-1048)\n", isStale, err)
return err
}
fmt.Fprintf(os.Stderr, "Debug: daemon detected stale JSONL, auto-importing with timeout... (bd-1048)\n")
// Create timeout context for import operation (bd-8931, bd-1048)
// This prevents daemon from hanging if import gets stuck
// Use shorter timeout (5s) to ensure client doesn't timeout waiting for response