{"record":{"id":"b5d05b244260874a","repo":"gastownhall/beads","slug":"failed-to-get-issue-s-w","errorCode":null,"errorMessage":"failed to get issue %s: %w","messagePattern":"failed to get issue (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/relate.go","lineNumber":178,"sourceCode":"\tvar err error\n\tid1, err = utils.ResolvePartialID(ctx, store, args[0])\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to resolve %s: %w\", args[0], err)\n\t}\n\tid2, err = utils.ResolvePartialID(ctx, store, args[1])\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to resolve %s: %w\", args[1], err)\n\t}\n\n\t// Get both issues\n\tvar issue1, issue2 *types.Issue\n\tissue1, err = store.GetIssue(ctx, id1)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get issue %s: %w\", id1, err)\n\t}\n\tissue2, err = store.GetIssue(ctx, id2)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get issue %s: %w\", id2, err)\n\t}\n\n\tif issue1 == nil {\n\t\treturn fmt.Errorf(\"issue not found: %s\", id1)\n\t}\n\tif issue2 == nil {\n\t\treturn fmt.Errorf(\"issue not found: %s\", id2)\n\t}\n\n\t// Remove relates-to dependency in both directions\n\t// Per Decision 004, relates-to links are now stored in dependencies table.\n\t// bd unrelate is an explicit dependency verb, so it records history\n\t// (EmitEvent) like bd dep remove; only structural teardown stays silent.\n\t// Remove id1 -> id2\n\tif err := store.RemoveDependencyWithOptions(ctx, id1, id2, actor, storage.DependencyRemoveOptions{EmitEvent: true}); err != nil {\n\t\treturn fmt.Errorf(\"failed to remove relates-to %s -> %s: %w\", id1, id2, err)\n\t}\n\t// Remove id2 -> id1 (bidirectional)","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/relate.go#L160-L196","documentation":"runUnrelate (bd unrelate) looks up both endpoint issues before removing a relates-to link; this wraps a store.GetIssue error for the first ID. Unlike 'issue not found', the storage layer returned a real error — the lookup itself failed, so bd cannot tell whether the issue exists.","triggerScenarios":"store.GetIssue(ctx, id1) returns a non-nil error: database file locked or corrupted, storage/driver failure, context cancellation mid-query, or an underlying SQL/driver error while reading the issues table.","commonSituations":"Another bd process or sync operation holding the database; a crashed writer leaving the Dolt/SQLite store inconsistent; network filesystem hosting .beads dropped mid-command; running bd while a migration is in progress.","solutions":["Read the wrapped inner error — it identifies the storage failure (locked DB, I/O error, corruption); fix that root cause first.","If the database is locked, wait for the concurrent `bd` command / `bd dolt` sync to finish and retry; avoid running writers in parallel on the same repo.","Verify database integrity with `bd doctor` and restore from backup (or re-clone the repo and re-sync) if corruption is reported.","Retry the unrelate command — transient I/O or context timeouts often succeed on a second attempt.","Confirm you are running bd in the repository that actually contains the issues, not a stale copy of .beads."],"exampleFix":"// before\n$ bd unrelate bd-1 bd-2   # while `bd dolt pull` holds the DB\nfailed to get issue bd-1: database is locked\n// after\n$ bd dolt pull && bd unrelate bd-1 bd-2","handlingStrategy":"try-catch","validationCode":"for _, id := range []string{id1, id2} {\n\tif !strings.HasPrefix(id, \"bd-\") {\n\t\treturn fmt.Errorf(\"%q does not look like an issue id\", id)\n\t}\n}\nif _, err := os.Stat(filepath.Join(repoRoot, \".beads\")); err != nil {\n\treturn fmt.Errorf(\"no beads database in %s\", repoRoot)\n}","typeGuard":null,"tryCatchPattern":"issue, err := store.GetIssue(ctx, id)\nif err != nil {\n\tif errors.Is(err, ErrDatabaseLocked) || isTransient(err) {\n\t\t// wait for concurrent writer / sync, then retry once\n\t\ttime.Sleep(time.Second)\n\t\tissue, err = store.GetIssue(ctx, id)\n\t}\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get issue %s: %w\", id, err)\n\t}\n}","preventionTips":["Do not run concurrent bd writers or `bd dolt` syncs against the same repo mid-command.","Run `bd doctor` after crashes to detect storage corruption early.","Run bd from the repository that actually contains the issues.","Retry transient storage errors once before treating them as fatal."],"tags":["go","storage","database","unrelate","cli"],"backgroundTag":"issue-lookup-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}