{"record":{"id":"765f560033c5a068","repo":"gastownhall/beads","slug":"query-wisp-dependents-w","errorCode":null,"errorMessage":"query wisp dependents: %w","messagePattern":"query wisp dependents: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/bulk_ops.go","lineNumber":389,"sourceCode":"\n\tfor len(toProcess) > 0 {\n\t\tif len(seen) > maxResults {\n\t\t\treturn discovered, fmt.Errorf(\"wisp cascade traversal discovered over %d issues; aborting\", maxResults)\n\t\t}\n\n\t\tend := batchSize\n\t\tif end > len(toProcess) {\n\t\t\tend = len(toProcess)\n\t\t}\n\t\tbatch := toProcess[:end]\n\t\ttoProcess = toProcess[end:]\n\n\t\tplaceholders, args := buildSQLInClause(batch)\n\t\trows, err := tx.QueryContext(ctx,\n\t\t\tfmt.Sprintf(`SELECT issue_id FROM wisp_dependencies WHERE %s IN (%s)`, DepTargetExpr, placeholders),\n\t\t\targs...)\n\t\tif err != nil {\n\t\t\treturn discovered, fmt.Errorf(\"query wisp dependents: %w\", err)\n\t\t}\n\n\t\tfor rows.Next() {\n\t\t\tvar depID string\n\t\t\tif err := rows.Scan(&depID); err != nil {\n\t\t\t\t_ = rows.Close()\n\t\t\t\treturn discovered, fmt.Errorf(\"scan wisp dependent: %w\", err)\n\t\t\t}\n\t\t\tif !seen[depID] {\n\t\t\t\tseen[depID] = true\n\t\t\t\tdiscovered[depID] = true\n\t\t\t\ttoProcess = append(toProcess, depID)\n\t\t\t}\n\t\t}\n\t\t_ = rows.Close()\n\t\tif err := rows.Err(); err != nil {\n\t\t\treturn discovered, fmt.Errorf(\"iterate wisp dependents: %w\", err)\n\t\t}","sourceCodeStart":371,"sourceCodeEnd":407,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/bulk_ops.go#L371-L407","documentation":"This error wraps a failure of the batched query `SELECT issue_id FROM wisp_dependencies WHERE <target> IN (...)` used during the recursive dependent traversal. The query failed at the driver level, so the traversal stops and returns whatever was already discovered alongside the error.","triggerScenarios":"Calling FindWispDependentsRecursiveInTx when a batch SELECT fails: connection drop, lock contention on wisp_dependencies, too-many-parameters from an oversized batch, or schema mismatch on DepTargetExpr's underlying column.","commonSituations":"Flaky network to the Dolt server mid-traversal; concurrent writes locking wisp_dependencies; version skew where the code expects a column the table doesn't have; batch size exceeding driver placeholder limits.","solutions":["Retry the traversal; the discovered set returned with the error can seed a resume.","Check the wrapped driver error — if it's a lock timeout, reduce concurrent writes to wisp_dependencies.","Verify the wisp_dependencies schema/DepTargetExpr column exists after upgrades.","Reduce batch size if the driver reports a placeholder/parameter limit."],"exampleFix":"// before\nids, err := store.FindWispDependentsRecursive(ctx, tx, rootID, max) // transient connection drop\n// after\nvar ids map[string]bool\nfor attempt := 0; attempt < 3; attempt++ {\n    ids, err = store.FindWispDependentsRecursive(ctx, tx, rootID, max)\n    if err == nil { break }\n    time.Sleep(time.Second * time.Duration(attempt+1))\n}","handlingStrategy":"retry","validationCode":"if err := store.Ping(ctx); err != nil {\n    return fmt.Errorf(\"storage unreachable; skip traversal: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"var lastErr error\nfor attempt := 0; attempt < 3; attempt++ {\n    ids, err := store.FindWispDependentsRecursive(ctx, tx, rootID, max)\n    if err == nil { return ids, nil }\n    lastErr = err\n    if !strings.Contains(err.Error(), \"query wisp dependents:\") { return nil, err }\n    time.Sleep(time.Second << attempt)\n}\nreturn nil, lastErr","preventionTips":["Use bounded retries with backoff for traversal queries.","Avoid heavy concurrent writes to wisp_dependencies during traversals.","Verify schema after upgrades (DepTargetExpr column present)."],"tags":["database","query","wisp","dependencies"],"backgroundTag":"query-execution-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}