gastownhall/beads · error

line %d (%s): %w

Error message

line %d (%s): %w

What it means

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).

Source

Thrown at cmd/bd/batch.go:181

		ctx := rootCtx
		if ctx == nil {
			ctx = context.Background()
		}

		// One transaction, one commit message, whole-batch rollback on the first
		// failing line — the contract is the same on both backends; only the
		// transaction primitive differs (uow.RunTx there, transact here), and
		// both wrap a per-op dispatch that shares this file's parser.
		var results []batchOpResult
		if proxied {
			results, err = runBatchProxiedServer(ctx, ops, commitMsg)
		} else {
			results = make([]batchOpResult, 0, len(ops))
			err = transact(ctx, store, commitMsg, func(tx storage.Transaction) error {
				for _, op := range ops {
					res, rerr := runBatchOp(ctx, tx, op)
					if rerr != nil {
						return fmt.Errorf("line %d (%s): %w", op.line, op.raw, rerr)
					}
					results = append(results, res)
				}
				return nil
			})
		}
		if err != nil {
			if jsonOutput {
				if jerr := outputJSONError(err, "batch_error"); jerr != nil {
					return errors.Join(err, jerr)
				}
			}
			return err
		}

		commandDidWrite.Store(true)

		if jsonOutput {

View on GitHub (pinned to 71377f2769)

Solutions

  1. 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).
  2. Verify referenced issue IDs exist with `bd show <id>` before batching.
  3. Split the batch file to isolate the failing op; note no partial commits happen — fix and re-run the whole file.
  4. Check the inner %w error for the storage-level cause (e.g. 'not found', constraint violation).

Example fix

// before (batch file)
close bd-1042
close bd-9999   <- not found
// after
close bd-1042
close bd-1043   <- verified existing ID
Defensive patterns

Strategy: try-catch

Validate before calling

# Before running the batch, verify all referenced IDs exist:
bd list --json | jq -r '.[].id' | sort > /tmp/known.ids
grep -oE 'bd-[0-9]+' batch.txt | sort -u | while read id; do grep -qx "$id" /tmp/known.ids || echo "missing: $id"; done

Try / catch

err := bdBatch(scriptFile)
if err != nil {
    var lineErr interface{ Line() int }
    if m := regexp.MustCompile(`line (\d+) \((.*)\): (.*)`).FindStringSubmatch(err.Error()); m != nil {
        log.Fatalf("batch failed at line %s (%s): %s — nothing was committed", m[1], m[2], m[3])
    }
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/296e1a8973c9ad72. Report an issue: GitHub.