{"record":{"id":"296e1a8973c9ad72","repo":"gastownhall/beads","slug":"line-d-s-w","errorCode":null,"errorMessage":"line %d (%s): %w","messagePattern":"line (.+?) \\((.+?)\\): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/batch.go","lineNumber":181,"sourceCode":"\t\tctx := rootCtx\n\t\tif ctx == nil {\n\t\t\tctx = context.Background()\n\t\t}\n\n\t\t// One transaction, one commit message, whole-batch rollback on the first\n\t\t// failing line — the contract is the same on both backends; only the\n\t\t// transaction primitive differs (uow.RunTx there, transact here), and\n\t\t// both wrap a per-op dispatch that shares this file's parser.\n\t\tvar results []batchOpResult\n\t\tif proxied {\n\t\t\tresults, err = runBatchProxiedServer(ctx, ops, commitMsg)\n\t\t} else {\n\t\t\tresults = make([]batchOpResult, 0, len(ops))\n\t\t\terr = transact(ctx, store, commitMsg, func(tx storage.Transaction) error {\n\t\t\t\tfor _, op := range ops {\n\t\t\t\t\tres, rerr := runBatchOp(ctx, tx, op)\n\t\t\t\t\tif rerr != nil {\n\t\t\t\t\t\treturn fmt.Errorf(\"line %d (%s): %w\", op.line, op.raw, rerr)\n\t\t\t\t\t}\n\t\t\t\t\tresults = append(results, res)\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t})\n\t\t}\n\t\tif err != nil {\n\t\t\tif jsonOutput {\n\t\t\t\tif jerr := outputJSONError(err, \"batch_error\"); jerr != nil {\n\t\t\t\t\treturn errors.Join(err, jerr)\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\n\t\tcommandDidWrite.Store(true)\n\n\t\tif jsonOutput {","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/batch.go#L163-L199","documentation":"During `bd batch` execution, each parsed operation runs inside a single storage transaction; if `runBatchOp` fails for any op, the whole transaction is rolled back and the error is wrapped with the source line number and the raw line text. This lets you locate the exact failing command in a batch script while preserving the underlying storage error. All prior ops in the batch are discarded (atomic batch semantics).","triggerScenarios":"Running `bd batch` (from a file via -f or piped stdin) where an individual operation fails inside `runBatchOp` — e.g. `close bd-999` for a nonexistent issue ID, an `update` with invalid field values, or a `dep add` referencing missing issues.","commonSituations":"Batch scripts generated against an older database where referenced issue IDs no longer exist; typos in issue IDs inside large batch files; dependency edges that violate constraints (e.g. cycles or self-dependencies); scripts copied from another repo with different issue IDs.","solutions":["Read the wrapped 'line %d (%s)' prefix to find the failing line in your batch script and fix the command there (usually a bad issue ID).","Verify referenced issue IDs exist with `bd show <id>` before batching.","Split the batch file to isolate the failing op; note no partial commits happen — fix and re-run the whole file.","Check the inner %w error for the storage-level cause (e.g. 'not found', constraint violation)."],"exampleFix":"// before (batch file)\nclose bd-1042\nclose bd-9999   <- not found\n// after\nclose bd-1042\nclose bd-1043   <- verified existing ID","handlingStrategy":"try-catch","validationCode":"# Before running the batch, verify all referenced IDs exist:\nbd list --json | jq -r '.[].id' | sort > /tmp/known.ids\ngrep -oE 'bd-[0-9]+' batch.txt | sort -u | while read id; do grep -qx \"$id\" /tmp/known.ids || echo \"missing: $id\"; done","typeGuard":null,"tryCatchPattern":"err := bdBatch(scriptFile)\nif err != nil {\n    var lineErr interface{ Line() int }\n    if m := regexp.MustCompile(`line (\\d+) \\((.*)\\): (.*)`).FindStringSubmatch(err.Error()); m != nil {\n        log.Fatalf(\"batch failed at line %s (%s): %s — nothing was committed\", m[1], m[2], m[3])\n    }\n    return err\n}","preventionTips":["Run `bd batch --dry-run` first; note it parses only — verify IDs against `bd list` separately.","Generate batch files from a query of existing issue IDs rather than hardcoding them.","Treat batches as all-or-nothing: fix the reported line and re-run the entire file.","Keep batch scripts in version control so failed runs are reproducible."],"tags":["cli","batch","transaction","go"],"backgroundTag":"batch-op-failed-atomic-rollback","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}