gastownhall/beads · error
failed to close duplicate: %w
Error message
failed to close duplicate: %w
What it means
Wraps store.CloseIssue failure after the dependency edge was successfully added in runDuplicate. The duplicate link exists but the lifecycle close of the duplicate issue failed, leaving the issue in an inconsistent intermediate state (linked but still open). Because the dep was already written, retrying is safe — the same 'duplicates' edge is idempotent in practice or the command should be re-run carefully.
Source
Thrown at cmd/bd/duplicate.go:113
canonical, err = store.GetIssue(ctx, canonicalID)
if err != nil || canonical == nil {
return fmt.Errorf("canonical issue not found: %s", canonicalID)
}
// Add a "duplicates" dependency edge (duplicate → canonical)
dep := &types.Dependency{
IssueID: duplicateID,
DependsOnID: canonicalID,
Type: types.DepDuplicates,
}
if err := store.AddDependency(ctx, dep, actor); err != nil {
return fmt.Errorf("failed to add duplicate link: %w", err)
}
// Close the duplicate issue through the lifecycle operation so it records
// the complete closure state.
if err := store.CloseIssue(ctx, duplicateID, "", actor, ""); err != nil {
return fmt.Errorf("failed to close duplicate: %w", err)
}
commandDidWrite.Store(true)
if isJSONOutput() {
return outputJSON(map[string]interface{}{
"duplicate": duplicateID,
"canonical": canonicalID,
"status": "closed",
})
}
fmt.Printf("%s Marked %s as duplicate of %s (closed)\n", ui.RenderPass("✓"), duplicateID, canonicalID)
return nil
}
func runSupersede(cmd *cobra.Command, args []string) error {
if usesProxiedServer() {View on GitHub (pinned to 71377f2769)
Solutions
- Check the issue state with `bd show <duplicate-id>` — it may already be closed; if so, nothing else is needed
- If still open, re-run `bd duplicate` (edge addition is tolerated) or `bd close <duplicate-id>` directly
- Check storage health if write errors persist
- Resolve concurrency: ensure no other agent is closing the same issue simultaneously
Example fix
// before Error: failed to close duplicate: storage write failed $ bd show bd-42 # still open // after $ bd close bd-42 --reason "duplicate of bd-17"
Defensive patterns
Strategy: try-catch
Validate before calling
iss, err := store.GetIssue(ctx, duplicateID)
if err != nil { return err }
if iss.Status == types.StatusClosed { return nil } // already closed, nothing to do Try / catch
if err := store.CloseIssue(ctx, duplicateID, "", actor, ""); err != nil {
if iss, gerr := store.GetIssue(ctx, duplicateID); gerr == nil && iss.Status == types.StatusClosed {
return nil // already closed concurrently; treat as success
}
return fmt.Errorf("failed to close duplicate: %w", err)
} Prevention
- Check issue status before closing to tolerate concurrent closes
- Serialize duplicate-marking across agents with a lock or bd claim
- Retry close once on transient storage errors
When it happens
Trigger: CloseIssue returns an error: issue already closed with a conflicting state, storage write failure, validation of closure fields rejected, or a driver error mid-transaction.
Common situations: A concurrent process closed the issue first; DB lock/timeout during the close write; store-level lifecycle validation failure; disk full during the write.
Related errors
- canonical issue not found: %s
- failed to add duplicate link: %w
- %w: %s
- %w: %w
- no store is open for this workspace
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/755dd4dae976df6d.
Report an issue: GitHub.