gastownhall/beads · error
query dependents from %s: %w
Error message
query dependents from %s: %w
What it means
ExternalDependentsBySourceInTx queries each dependency plane ('dependencies', 'wisp_dependencies') in batches for rows depending on the given ids. This error wraps a query-execution failure and names the offending table. A missing optional table is deliberately skipped via optionalBlockedTable + isTableNotExistError, so reaching this error means a real failure, not an absent plane.
Source
Thrown at internal/storage/issueops/delete_role.go:207
}
bySource := make(map[string]map[string]bool)
for i := 0; i < len(ids); i += deleteBatchSize {
end := i + deleteBatchSize
if end > len(ids) {
end = len(ids)
}
inClause, args := buildSQLInClause(ids[i:end])
for _, depTable := range []string{"dependencies", "wisp_dependencies"} {
rows, err := tx.QueryContext(ctx,
fmt.Sprintf(`SELECT %s AS depends_on_id, issue_id FROM %s WHERE %s`,
DepTargetExpr, depTable, depTargetIn("", inClause)),
args...)
if err != nil {
if optionalBlockedTable(depTable) && isTableNotExistError(err) {
continue
}
return nil, fmt.Errorf("query dependents from %s: %w", depTable, err)
}
for rows.Next() {
var target, dependent string
if err := rows.Scan(&target, &dependent); err != nil {
_ = rows.Close()
return nil, fmt.Errorf("scan dependent: %w", err)
}
if idSet[dependent] {
continue
}
if bySource[target] == nil {
bySource[target] = make(map[string]bool)
}
bySource[target][dependent] = true
}
_ = rows.Close()
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("iterate dependents from %s: %w", depTable, err)View on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped driver error and the named table in the message
- If the table should be optional, check whether isTableNotExistError recognizes your driver's error (driver/version mismatch)
- Restore connectivity or the transaction and retry
- Update the storage driver/backend to a compatible version
- Retry the operation; the query is read-only and safe to re-run
Defensive patterns
Strategy: try-catch
Validate before calling
// confirm both planes exist before deleting on your backend
for _, t := range []string{"dependencies", "wisp_dependencies"} {
if err := store.PingTable(ctx, t); err != nil { return fmt.Errorf("missing table %s", t) }
} Type guard
if strings.Contains(err.Error(), "query dependents from ") {
table := extractTable(err) // which plane failed
_ = table
} Try / catch
_, err := store.Delete(ctx, req)
if err != nil && strings.Contains(err.Error(), "query dependents from") {
log.Printf("dependents query failed: %v", errors.Unwrap(err))
} Prevention
- Run migrations before delete operations
- Check driver error-text compatibility for optional-table skipping
- Use read-only probes of the dependency tables in health checks
- Keep contexts alive for the whole delete
When it happens
Trigger: tx.QueryContext on 'dependencies' or 'wisp_dependencies' returns an error that is not a tolerated 'table not exist' — connection failure, SQL/driver error, or cancelled context inside the batched IN query.
Common situations: DB connection dropped mid-delete; context cancellation; driver incompatibility producing unexpected SQL errors; a genuinely absent optional table whose error text is not recognized by isTableNotExistError on your driver version.
Related errors
- iter dependents: query: %w
- query neighbors from %s: %w
- compare local HEAD to %s: %w
- failed to begin transaction: %w
- failed to recompute is_blocked: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/1cd8d67dfad2098e.
Report an issue: GitHub.