gastownhall/beads · error

failed to check dependency target %s for %s: %w

Error message

failed to check dependency target %s for %s: %w

What it means

PersistDependenciesWithOptionsResult validates each dependency's target: for non-external targets it looks up DependsOnID in the lookup table. If the lookup query fails (anything other than sql.ErrNoRows, which is handled as 'target not found' and skipped), the error is wrapped as 'failed to check dependency target <target> for <issue>'. This is a query-failure path, distinct from the handled missing-target case.

Source

Thrown at internal/storage/issueops/create.go:911

			}
			isCrossPrefix := types.ExtractPrefix(dep.IssueID) != types.ExtractPrefix(dep.DependsOnID)
			kind := ClassifyDepTarget(ctx, tx, dep, isCrossPrefix)

			if kind != DepTargetExternal {
				lookupTable := "issues"
				if kind == DepTargetWisp {
					lookupTable = "wisps"
				}
				var exists int
				//nolint:gosec // G201: lookupTable is one of two hardcoded constants
				if err := tx.QueryRowContext(ctx,
					fmt.Sprintf("SELECT 1 FROM %s WHERE id = ?", lookupTable),
					dep.DependsOnID).Scan(&exists); err != nil {
					if err == sql.ErrNoRows {
						recordSkippedDependency(opts, dep, "target not found")
						continue
					}
					return result, fmt.Errorf("failed to check dependency target %s for %s: %w", dep.DependsOnID, dep.IssueID, err)
				}
			}

			if kind != DepTargetExternal && types.ExtractPrefix(dep.IssueID) == types.ExtractPrefix(dep.DependsOnID) {
				if err := CheckBlockingHierarchyInTx(ctx, tx, dep, nil); err != nil {
					if opts.SkipDependencyValidationErrors {
						recordSkippedDependency(opts, dep, err.Error())
						continue
					}
					return result, fmt.Errorf("invalid dependency %s -> %s: %w", dep.IssueID, dep.DependsOnID, err)
				}
			}

			if err := CheckDependencyCycleInTx(ctx, tx, dep, nil); err != nil {
				if opts.SkipDependencyValidationErrors {
					recordSkippedDependency(opts, dep, err.Error())
					continue
				}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the wrapped %w error for the SQL root cause (no such table, connection refused, ctx cancelled) and fix it.
  2. Run schema initialization/migrations so the issues lookup table exists before importing dependencies.
  3. Retry the import after connectivity is restored; use SetSkipDependencyValidationErrors only for soft validation errors, not query failures.
  4. Increase the context budget or split the import into smaller batches so validation completes within the deadline.

Example fix

// before
ctx, cancel := context.WithTimeout(ctx, 1*time.Second)
defer cancel()
result, err := issueops.PersistDependenciesWithResult(ctx, tx, deps, opts) // ctx cancelled mid-lookup
// after
ctx, cancel := context.WithTimeout(ctx, 60*time.Second)
defer cancel()
result, err := issueops.PersistDependenciesWithResult(ctx, tx, deps, opts)
Defensive patterns

Strategy: validation

Validate before calling

// pre-verify dependency targets exist before persisting
for _, dep := range deps {
    var n int
    if err := tx.QueryRowContext(ctx,
        "SELECT COUNT(*) FROM issues WHERE id = ?", dep.DependsOnID).Scan(&n); err != nil {
        return err
    }
    if n == 0 { return fmt.Errorf("missing dependency target %s", dep.DependsOnID) }
}

Try / catch

result, err := issueops.PersistDependenciesWithResult(ctx, tx, deps, opts)
if err != nil && strings.Contains(err.Error(), "failed to check dependency target") {
    if isTransient(err) {
        return retryWithBackoff(ctx, func() error {
            _, e := issueops.PersistDependenciesWithResult(ctx, tx, deps, opts)
            return e
        })
    }
    return err
}

Prevention

When it happens

Trigger: Creating issues with dependencies via CreateIssuesInTxWithContext / PersistDependenciesWithResult when the SELECT 1 FROM <lookupTable> WHERE id = ? query errors — missing/corrupt lookup table, connection failure, cancelled context, or malformed SQL due to table-name drift.

Common situations: Bulk import against a half-migrated schema; remote Dolt server connection dropping mid-import; context cancellation during long dependency validation; running tests/importers against an uninitialized database.

Related errors


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