{"record":{"id":"b240999d84a6ae78","repo":"gastownhall/beads","slug":"get-dependencies-rows-from-s-w","errorCode":null,"errorMessage":"get dependencies: rows from %s: %w","messagePattern":"get dependencies: rows from (.+?): %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/dependencies.go","lineNumber":1122,"sourceCode":"\t// Query both dependency tables to find all dependencies.\n\tvar deps []depMeta\n\tfor _, depTable := range []string{\"dependencies\", \"wisp_dependencies\"} {\n\t\trows, err := tx.QueryContext(ctx, fmt.Sprintf(\n\t\t\t`SELECT %s AS depends_on_id, type FROM %s WHERE issue_id = ?`, DepTargetExpr, depTable), issueID)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"get dependencies from %s: %w\", depTable, err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\tvar d depMeta\n\t\t\tif scanErr := rows.Scan(&d.depID, &d.depType); scanErr != nil {\n\t\t\t\t_ = rows.Close()\n\t\t\t\treturn nil, fmt.Errorf(\"get dependencies: scan: %w\", scanErr)\n\t\t\t}\n\t\t\tdeps = append(deps, d)\n\t\t}\n\t\t_ = rows.Close()\n\t\tif err := rows.Err(); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"get dependencies: rows from %s: %w\", depTable, err)\n\t\t}\n\t}\n\n\tif len(deps) == 0 {\n\t\treturn nil, nil\n\t}\n\n\t// Fetch all dependency target issues.\n\tids := make([]string, len(deps))\n\tfor i, d := range deps {\n\t\tids[i] = d.depID\n\t}\n\tissues, err := GetIssuesByIDsInTx(ctx, tx, ids, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"get dependencies: fetch issues: %w\", err)\n\t}\n\tissueMap := make(map[string]*types.Issue, len(issues))\n\tfor _, iss := range issues {","sourceCodeStart":1104,"sourceCodeEnd":1140,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/dependencies.go#L1104-L1140","documentation":"This error wraps a failure reported by rows.Err() while iterating dependency rows for an issue in GetDependenciesWithMetadataInTx. The driver-level query succeeded initially, but the row stream hit an error mid-iteration (connection drop, context cancellation, driver decode failure) on one of the two dependency tables (\"dependencies\" or \"wisp_dependencies\"). The %s names which table was being read so you can tell whether regular or wisp dependency rows failed.","triggerScenarios":"Calling GetDependenciesWithMetadataInTx (via buildDependencyTreeInTx or ExecuteRelated) when the underlying SQL connection dies or the context is cancelled while rows from dependencies/wisp_dependencies are still being drained.","commonSituations":"Long dependency-tree traversals whose connection times out mid-scan; user Ctrl-C or deadline expiry cancelling ctx mid-iteration; flaky network to a remote Dolt/MySQL server; driver errors surfaced lazily by database/sql only at rows.Err().","solutions":["Check the wrapped driver error in the %w chain for connection/context issues and inspect the named table (\"dependencies\" vs \"wisp_dependencies\").","Ensure the context passed in has an adequate deadline; avoid cancelling the request mid-traversal.","Verify DB connectivity/stability (keepalives, connection pool settings like ConnMaxLifetime).","Retry the operation on a fresh transaction if the wrapped error is transient (connection reset, driver: bad connection)."],"exampleFix":"// before: no deadline management, long tree walk killed mid-rows\nctx := context.Background()\ndeps, err := GetDependenciesWithMetadataInTx(ctx, tx, issueID)\n\n// after: give the traversal a sane deadline and handle transient errors\nctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)\ndefer cancel()\ndeps, err := GetDependenciesWithMetadataInTx(ctx, tx, issueID)\nif err != nil && isTransient(err) { deps, err = retry(...) }","handlingStrategy":"try-catch","validationCode":"// Ensure a healthy connection and adequate deadline before the call\nif err := tx.PingContext(ctx); err != nil { return err }\nctx, cancel := context.WithTimeout(ctx, 30*time.Second)\ndefer cancel()","typeGuard":"func isRowsIterationErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"rows from \")\n}","tryCatchPattern":"deps, err := GetDependenciesWithMetadataInTx(ctx, tx, issueID)\nif err != nil {\n    var netErr net.Error\n    if errors.As(err, &netErr) || errors.Is(err, context.DeadlineExceeded) {\n        return retryWithFreshTx(ctx, issueID)\n    }\n    return fmt.Errorf(\"dependency metadata lookup failed: %w\", err)\n}","preventionTips":["Always pass a context with a realistic timeout for dependency traversals.","Keep ConnMaxLifetime below the server wait_timeout to avoid reaped connections.","Check rows-scoped errors at the source: log the wrapped driver error, not just the wrapper.","Monitor connection-pool health in long-running services."],"tags":["database","sql","go","rows-iteration"],"backgroundTag":"sql-rows-iteration-error","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}