{"record":{"id":"46771176efd25285","repo":"gastownhall/beads","slug":"failed-to-add-duplicate-link-w","errorCode":null,"errorMessage":"failed to add duplicate link: %w","messagePattern":"failed to add duplicate link: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/duplicate.go","lineNumber":107,"sourceCode":"\tif duplicateID == canonicalID {\n\t\treturn fmt.Errorf(\"cannot mark an issue as duplicate of itself\")\n\t}\n\n\t// Verify canonical issue exists\n\tvar canonical *types.Issue\n\tcanonical, err = store.GetIssue(ctx, canonicalID)\n\tif err != nil || canonical == nil {\n\t\treturn fmt.Errorf(\"canonical issue not found: %s\", canonicalID)\n\t}\n\n\t// Add a \"duplicates\" dependency edge (duplicate → canonical)\n\tdep := &types.Dependency{\n\t\tIssueID:     duplicateID,\n\t\tDependsOnID: canonicalID,\n\t\tType:        types.DepDuplicates,\n\t}\n\tif err := store.AddDependency(ctx, dep, actor); err != nil {\n\t\treturn fmt.Errorf(\"failed to add duplicate link: %w\", err)\n\t}\n\n\t// Close the duplicate issue through the lifecycle operation so it records\n\t// the complete closure state.\n\tif err := store.CloseIssue(ctx, duplicateID, \"\", actor, \"\"); err != nil {\n\t\treturn fmt.Errorf(\"failed to close duplicate: %w\", err)\n\t}\n\n\tcommandDidWrite.Store(true)\n\n\tif isJSONOutput() {\n\t\treturn outputJSON(map[string]interface{}{\n\t\t\t\"duplicate\": duplicateID,\n\t\t\t\"canonical\": canonicalID,\n\t\t\t\"status\":    \"closed\",\n\t\t})\n\t}\n","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/duplicate.go#L89-L125","documentation":"Wraps store.AddDependency failure when creating the 'duplicates' dependency edge (duplicate → canonical) in runDuplicate. The store refused or failed to persist the dependency — storage-level error, constraint violation, or a driver write failure. The duplicate issue is NOT closed in this case because the command aborts before CloseIssue.","triggerScenarios":"AddDependency returns an error: storage write failure, dependency validation (e.g. circular/self dependency rejected downstream), duplicate edge conflicts, or driver/DB errors from the Dolt backend.","commonSituations":"Database locked or out of disk space during a write; corrupted store; driver-level constraint triggered by an unexpected pre-existing dependency; running against a read-only replica.","solutions":["Re-run the command — transient write failures often clear on retry","Check storage health (disk space, DB lock, `bd doctor`)","Inspect existing dependencies (`bd dep <id>`) and remove a conflicting edge if present","Verify you are not writing to a read-only store/replica"],"exampleFix":"// before\n$ bd duplicate bd-42 --duplicate-of bd-17  # disk full\nError: failed to add duplicate link: disk I/O error\n// after\n$ df -h && rm -rf /tmp/cache && bd duplicate bd-42 --duplicate-of bd-17","handlingStrategy":"retry","validationCode":"// pre-check storage writability and existing deps\nif _, err := store.GetIssue(ctx, canonicalID); err != nil { return err }\nif err := diskHasSpace(); err != nil { return err }","typeGuard":null,"tryCatchPattern":"err := store.AddDependency(ctx, dep, actor)\nfor i := 0; i < 3 && err != nil; i++ {\n    time.Sleep(backoff(i))\n    err = store.AddDependency(ctx, dep, actor)\n}\nif err != nil { return fmt.Errorf(\"failed to add duplicate link: %w\", err) }","preventionTips":["Ensure disk space and no exclusive DB locks before batch duplicate operations","Check existing dependencies to avoid conflicting edges","Keep the Dolt driver healthy (bd doctor)"],"tags":["storage","dependency","duplicate"],"backgroundTag":"dependency-write-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}