gastownhall/beads · error
get dependencies from %s: %w
Error message
get dependencies from %s: %w
What it means
Wraps a QueryContext error while enumerating an issue's dependencies from one of the two dependency tables in GetDependenciesWithMetadataInTx. The table name is embedded so you know whether 'dependencies' or 'wisp_dependencies' failed.
Source
Thrown at internal/storage/issueops/dependencies.go:1110
}
// GetDependenciesWithMetadataInTx returns issues that the given issueID depends on,
// along with the dependency type. Works within an existing transaction.
// Queries both dependency tables to handle cross-table dependencies.
//
//nolint:gosec // G201: table names come from hardcoded constants
func GetDependenciesWithMetadataInTx(ctx context.Context, tx DBTX, issueID string) ([]*types.IssueWithDependencyMetadata, error) {
type depMeta struct {
depID, depType string
}
// Query both dependency tables to find all dependencies.
var deps []depMeta
for _, depTable := range []string{"dependencies", "wisp_dependencies"} {
rows, err := tx.QueryContext(ctx, fmt.Sprintf(
`SELECT %s AS depends_on_id, type FROM %s WHERE issue_id = ?`, DepTargetExpr, depTable), issueID)
if err != nil {
return nil, fmt.Errorf("get dependencies from %s: %w", depTable, err)
}
for rows.Next() {
var d depMeta
if scanErr := rows.Scan(&d.depID, &d.depType); scanErr != nil {
_ = rows.Close()
return nil, fmt.Errorf("get dependencies: scan: %w", scanErr)
}
deps = append(deps, d)
}
_ = rows.Close()
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("get dependencies: rows from %s: %w", depTable, err)
}
}
if len(deps) == 0 {
return nil, nil
}View on GitHub (pinned to 71377f2769)
Solutions
- Confirm both dependencies tables exist (run migrations)
- Address the wrapped driver error — often transient; retry
- Check for earlier statements in the transaction that aborted it
- If DepTargetExpr SQL fragment was customized, validate it against the driver
Defensive patterns
Strategy: validation
Validate before calling
// Preflight: verify both dependency tables exist before tree building:
for _, tbl := range []string{"dependencies", "wisp_dependencies"} {
var n int
err := db.QueryRowContext(ctx, `SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name = ?`, tbl).Scan(&n)
if err != nil || n == 0 { return fmt.Errorf("missing dependency table %s; run migrations", tbl) }
} Try / catch
deps, err := ops.GetDependenciesWithMetadataInTx(ctx, tx, issueID)
if err != nil && strings.Contains(err.Error(), "get dependencies from") {
if isMissingTable(err) { return runMigrationsThenRetry(ctx) }
if isTransientDBError(err) { deps, err = ops.GetDependenciesWithMetadataInTx(ctx, tx, issueID) }
if err != nil { return err }
} Prevention
- Run complete migrations so both dependency tables exist
- Avoid deep/unbounded tree walks that hold transactions open
- Validate custom SQL fragments (DepTargetExpr) against your driver
- Check for earlier transaction errors that may have aborted the tx
When it happens
Trigger: The `SELECT ... AS depends_on_id, type FROM <depTable> WHERE issue_id = ?` query fails for either table — missing table, driver error, or connection failure while building a dependency tree (via buildDependencyTreeInTx or ExecuteRelated).
Common situations: Partial migration leaving wisp_dependencies absent; transaction aborted by an earlier error; connection drop mid-tree-build when walking deep dependency graphs.
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
- get dependencies: scan: %w
- failed to begin transaction: %w
- failed to recompute is_blocked: %w
- failed to commit is_blocked repairs: %w
- failed to query orphaned dependencies: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/2363fca812486ea5.
Report an issue: GitHub.