gastownhall/beads · error

check existing issues before import: %w

Error message

check existing issues before import: %w

What it means

The stale-guard pre-filter queries the local store with GetIssuesByIDs to compare incoming import rows against existing issues' updated_at. If that read fails, the import cannot safely decide which rows are stale, so it aborts with `check existing issues before import:` plus the cause. No data has been written.

Source

Thrown at cmd/bd/import_shared.go:717

		newIDsSeen[id] = struct{}{}
		plan.NewIDs = append(plan.NewIDs, id)
	}

	if len(ids) == 0 {
		// There is no ID to look up, but title-only rows still create on
		// execution. Classify each non-nil row before the short-circuit so a
		// dry run reports it as created rather than unchanged.
		for _, issue := range issues {
			if issue != nil {
				addNew(issue.ID)
			}
		}
		return issues, nil, plan, nil
	}

	localIssues, err := store.GetIssuesByIDs(ctx, ids)
	if err != nil {
		return nil, nil, plan, fmt.Errorf("check existing issues before import: %w", err)
	}
	localByID := make(map[string]*types.Issue, len(localIssues))
	for _, issue := range localIssues {
		if issue != nil && issue.ID != "" && !issue.UpdatedAt.IsZero() {
			localByID[issue.ID] = issue
		}
	}

	if len(localByID) == 0 {
		// Nothing matched locally, so every considered row is new.
		for _, issue := range issues {
			if issue == nil {
				continue
			}
			addNew(issue.ID)
		}
		return issues, nil, plan, nil
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the wrapped cause to find the storage-level failure.
  2. Ensure no other process holds the DB lock; retry after the competing process exits.
  3. Verify storage connectivity (daemon running, Dolt server reachable) with `bd doctor`.
  4. Run `bd doctor` / integrity checks if a schema or corruption issue is suspected, restoring from backup if needed.

Example fix

// before
bd import issues.jsonl   # check existing issues before import: database is locked
// after
fuser .beads/*.db         # find/stop the competing process
bd import issues.jsonl
Defensive patterns

Strategy: try-catch

Validate before calling

// quick connectivity probe before the import read
conn, err := store.GetIssuesByIDs(ctx, []string{})
if err != nil {
    return fmt.Errorf("storage unavailable, aborting import: %w", err)
}
_ = conn

Try / catch

_, _, _, err := filterStaleImportIssues(ctx, store, issues, allowStale)
if err != nil {
    var preErr error
    if strings.Contains(err.Error(), "check existing issues before import:") {
        // read-only stage failed; safe to retry after storage recovers
        preErr = fmt.Errorf("storage read failed, import aborted safely: %w", err)
    }
    return preErr
}

Prevention

When it happens

Trigger: Calling filterStaleImportIssues (via importIssuesCore, classifyDryRunImport, or the dry-run path) when the underlying GetIssuesByIDs read errors: storage unavailable, connection refused, locked DB, or query failure.

Common situations: SQLite DB locked by another process during `bd import` or `bd import --dry-run`; Dolt server unreachable; corrupted or migrated schema lacking expected columns; permissions problems after copying a database file.

Related errors


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