gastownhall/beads · error

db: DependencySQLRepository.IsBlocked %s: %w

Error message

db: DependencySQLRepository.IsBlocked %s: %w

What it means

IsBlocked delegates to issueops.IsBlockedInTx, which queries dependencies to determine whether an issue has open blockers and returns the blocker IDs. This wrapper indicates that the underlying in-transaction blocked-status query failed; the repository is merely adding context (repository name and issue ID) to the wrapped error.

Source

Thrown at internal/storage/domain/db/dependency.go:876

		return deps
	}
	allowed := make(map[types.DependencyType]struct{}, len(filter))
	for _, t := range filter {
		allowed[t] = struct{}{}
	}
	out := make([]*types.IssueWithDependencyMetadata, 0, len(deps))
	for _, d := range deps {
		if _, ok := allowed[d.DependencyType]; ok {
			out = append(out, d)
		}
	}
	return out
}

func (r *dependencySQLRepositoryImpl) IsBlocked(ctx context.Context, issueID string, opts domain.DepListOpts) (bool, []string, error) {
	blocked, blockers, err := issueops.IsBlockedInTx(ctx, r.runner, issueID)
	if err != nil {
		return false, nil, fmt.Errorf("db: DependencySQLRepository.IsBlocked %s: %w", issueID, err)
	}
	return blocked, blockers, nil
}

func (r *dependencySQLRepositoryImpl) DetectCycles(ctx context.Context) ([][]*types.Issue, error) {
	out, err := issueops.DetectCyclesInTx(ctx, r.runner)
	if err != nil {
		return nil, fmt.Errorf("db: DependencySQLRepository.DetectCycles: %w", err)
	}
	return out, nil
}

func (r *dependencySQLRepositoryImpl) DetectCycleReport(ctx context.Context) (publicops.CycleReport, error) {
	out, err := issueops.DetectCycleReportInTx(ctx, r.runner)
	if err != nil {
		return publicops.CycleReport{}, fmt.Errorf("db: DependencySQLRepository.DetectCycleReport: %w", err)
	}
	return out, nil

View on GitHub (pinned to 71377f2769)

Solutions

  1. Unwrap the error (errors.Unwrap / %v with %+v) to see the root cause from IsBlockedInTx.
  2. Verify database connectivity and that the schema is migrated.
  3. Retry with a fresh context if the cause was deadline/cancellation.
  4. Confirm the issue exists — an invalid ID can surface via the underlying query in some drivers.

Example fix

// before
blocked, blockers, err := repo.IsBlocked(ctx, id, opts)
if err != nil { return err }
// after: retry transient failures with a fresh context
blocked, blockers, err := repo.IsBlocked(ctx, freshCtx, id, opts)
if err != nil { return fmt.Errorf("is blocked %s: %w", id, err) }
Defensive patterns

Strategy: try-catch

Validate before calling

if err := db.PingContext(ctx); err != nil {
    return fmt.Errorf("database unreachable before IsBlocked: %w", err)
}

Type guard

func isDBUnreachable(err error) bool {
    return errors.Is(err, driver.ErrBadConn) || dberrors.IsTableNotExist(err)
}

Try / catch

blocked, blockers, err := repo.IsBlocked(ctx, id, opts)
if err != nil {
    var cause error
    errors.As(err, &cause) // inspect unwrapped driver error
    return fmt.Errorf("blocked check failed for %s: %w", id, err)
}

Prevention

When it happens

Trigger: Calling IsBlocked(ctx, issueID, opts) when the underlying query fails: missing/corrupt dependencies table, connection error, context cancellation, or driver error inside IsBlockedInTx.

Common situations: Database unavailable or Dolt server stopped; issue ID typed wrong (query itself usually still succeeds, so most often it is connectivity/schema); context deadline exceeded on a slow database during bulk operations.

Understand the failure class

Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.

Related errors


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