gastownhall/beads · error

import dependency pass chunk %d/%d failed (all %d issue rows

Error message

import dependency pass chunk %d/%d failed (all %d issue rows are committed; re-run the import to resume — it converges): %w

What it means

In the chunked classic import, issue rows are committed first, then a second pass wires deferred dependency rows in chunks. If a dependency-pass chunk fails, ALL issue rows are already durably committed — only the dependency edges are incomplete. The error states the row count committed and that re-running the import converges: the rows will be updated in place and the missing dependencies wired.

Source

Thrown at cmd/bd/import_shared.go:431

		return nil
	}
	depOpts := opts
	// Never rewrite an existing row here: the import's row write already
	// happened in phase 1, and a concurrent update since then must win. With
	// ConflictSkip the engine leaves the stored row untouched and still wires
	// the batch's dependencies.
	depOpts.ConflictSkip = true
	// No row write can be stale-rejected under ConflictSkip; leaving the
	// callback unset keeps a phase-2 signal from ever misreporting a row
	// whose phase-1 write committed.
	depOpts.OnStaleRejected = nil
	depTotal := len(depRows)
	depChunks := (depTotal + importChunkSize - 1) / importChunkSize
	for start, chunk := 0, 1; start < depTotal; start, chunk = start+importChunkSize, chunk+1 {
		end := min(start+importChunkSize, depTotal)
		pacer.beforeTx()
		if err := store.CreateIssuesWithFullOptions(ctx, depRows[start:end], actor, depOpts); err != nil {
			return fmt.Errorf("import dependency pass chunk %d/%d failed (all %d issue rows are committed; re-run the import to resume — it converges): %w", chunk, depChunks, rowTotal, err)
		}
		fmt.Fprintf(importProgress, "bd import: deferred dependencies wired for %d/%d issues\n", end, depTotal) //nolint:gosec // G705: stderr, not a browser context
	}
	return nil
}

// orderImportIssuesForChunking returns the issues reordered so that every valid
// readiness-affecting edge (blocks, parent-child, conditional-blocks, waits-for;
// the types GetReadyWork consults) points at a row in the same or an earlier
// chunk, which lets the import wire that edge in the same transaction as the
// row. It runs Kahn's algorithm over the intra-batch readiness edges, seeded in
// file order so unconstrained rows keep their relative order; duplicate IDs are
// chained in file order to preserve last-row-wins upsert semantics.
//
// A readiness cycle (invalid for blocking types; only ever present in the
// corrupted or legacy JSONL the import tolerates) cannot be fully ordered.
// Appending the stalled rows in plain file order — as an earlier version did —
// can place a valid dependent of a cycle before the cycle member it blocks on,

View on GitHub (pinned to 71377f2769)

Solutions

  1. Re-run the same import — all issue rows are committed; the retry wires the missing dependencies and converges.
  2. Fix the underlying storage issue named by the wrapped error (locks, disk, connectivity) before retrying.
  3. If it recurs, inspect the dependency records in the JSONL for references to nonexistent or filtered-out issues.
  4. Reduce competing bd activity during imports to avoid lock contention between passes.

Example fix

// before
bd import big.jsonl   # dependency pass chunk 2/3 failed (all 500 issue rows are committed...)
// after
# ensure no competing locks, then re-run:
bd import big.jsonl   # completes dependency wiring
Defensive patterns

Strategy: retry

Validate before calling

// validate dependency references exist before import
ids := map[string]bool{}
for _, iss := range issues { ids[iss.ID] = true }
for _, iss := range issues {
    for _, d := range iss.Dependencies {
        if !ids[d.DependsOnID] { return fmt.Errorf("dep on missing issue %s", d.DependsOnID) }
    }
}

Try / catch

if err := importIssuesChunked(ctx, store, issues, actor, opts); err != nil {
    if strings.Contains(err.Error(), "dependency pass") {
        // all issue rows committed; retry wires remaining deps and converges
        return retry(2, time.Second, func() error {
            return importIssuesChunked(ctx, store, issues, actor, opts)
        })
    }
    return err
}

Prevention

When it happens

Trigger: `bd import` where the issue-row pass succeeded but a dependency-pass CreateIssuesWithFullOptions chunk failed — storage lock contention, disk error, or a dependency row failing constraints (e.g. a dependency referencing an issue that failed filtering/validation).

Common situations: Concurrent bd process grabbing the SQLite write lock between the row pass and the dep pass; large dependency graphs on a flaky disk; mixed-bucket dependency policy dropping a referenced issue so its dep row errors.

Related errors


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