{"record":{"id":"a4e35631126e9bbb","repo":"gastownhall/beads","slug":"partition-wisp-ids-w","errorCode":null,"errorMessage":"partition wisp ids: %w","messagePattern":"partition wisp ids: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/wisp_routing.go","lineNumber":164,"sourceCode":"\t\t\tend = len(ids)\n\t\t}\n\t\tbatch := ids[start:end]\n\t\tplaceholders := make([]string, len(batch))\n\t\targs := make([]any, len(batch))\n\t\tfor i, id := range batch {\n\t\t\tplaceholders[i] = \"?\"\n\t\t\targs[i] = id\n\t\t}\n\t\t//nolint:gosec // G201: only ? placeholders in the IN clause.\n\t\trows, qErr := tx.QueryContext(ctx,\n\t\t\tfmt.Sprintf(\"SELECT id FROM wisps WHERE id IN (%s)\", strings.Join(placeholders, \",\")),\n\t\t\targs...)\n\t\tif qErr != nil {\n\t\t\t// Wisps table may not exist yet on older schemas — treat as \"no wisps\".\n\t\t\tif isTableNotExistError(qErr) {\n\t\t\t\treturn nil, append([]string(nil), ids...), nil\n\t\t\t}\n\t\t\treturn nil, nil, fmt.Errorf(\"partition wisp ids: %w\", qErr)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\tvar id string\n\t\t\tif scanErr := rows.Scan(&id); scanErr != nil {\n\t\t\t\t_ = rows.Close()\n\t\t\t\treturn nil, nil, fmt.Errorf(\"partition wisp ids: scan: %w\", scanErr)\n\t\t\t}\n\t\t\twispSet[id] = struct{}{}\n\t\t}\n\t\t_ = rows.Close()\n\t\tif rowsErr := rows.Err(); rowsErr != nil {\n\t\t\treturn nil, nil, fmt.Errorf(\"partition wisp ids: rows: %w\", rowsErr)\n\t\t}\n\t}\n\n\tfor _, id := range ids {\n\t\tif _, ok := wispSet[id]; ok {\n\t\t\twispIDs = append(wispIDs, id)","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/wisp_routing.go#L146-L182","documentation":"PartitionWispIDsInTx batches IDs into `SELECT id FROM wisps WHERE id IN (...)` queries. This error wraps a query execution failure that is not a table-not-exist error (that case is deliberately tolerated and treated as 'no wisps'). It indicates a real failure opening the rows: connection failure, SQL error, timeout, or permission problem.","triggerScenarios":"Calling PartitionWispIDsInTx (directly or through any of its six wrappers) when the batched IN-query against wisps fails with a driver/SQL error other than 'table does not exist' — e.g. connection reset, context deadline exceeded mid-query, or an SQL syntax/permission error.","commonSituations":"Remote Dolt connection dropped during bulk hydration of many issue IDs; context timeout hit because the batch was too large for the WAN link; mis-provisioned DB credentials revoked mid-session.","solutions":["Unwrap the driver error to identify the root cause (timeout, connection reset, permission)","Retry with a fresh transaction — the operation is read-only and idempotent","Reduce the number of IDs per call (or the batch size) so each chunk finishes within the deadline","Verify DB permissions and connectivity; check Dolt server logs for the corresponding failure"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if err := ctx.Err(); err != nil { return err } // fail fast before query\nif len(ids) == 0 { return nil }","typeGuard":null,"tryCatchPattern":"wispIDs, permIDs, err := issueops.PartitionWispIDsInTx(ctx, tx, ids)\nif err != nil {\n\tif errors.Is(err, context.DeadlineExceeded) {\n\t\t// chunk ids smaller and retry\n\t}\n\treturn err\n}","preventionTips":["Keep ID batches modest so each IN-query completes inside the deadline","Use bounded retries with backoff for transient driver errors","Verify DB permissions for the wisps table after role changes","Watch for non-'table not exist' SQL errors — they indicate a real problem, unlike the tolerated missing-table case"],"tags":["database","wisp-routing","query-execution"],"backgroundTag":"db-query-execution-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}