{"record":{"id":"d9885128d92c2c29","repo":"gastownhall/beads","slug":"count-inbound-dependencies-from-s-w","errorCode":null,"errorMessage":"count inbound dependencies from %s: %w","messagePattern":"count inbound dependencies from (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/delete.go","lineNumber":255,"sourceCode":"\teventsCount += wispEventsCount\n\n\tfor i := 0; i < len(set.All); i += deleteBatchSize {\n\t\tend := i + deleteBatchSize\n\t\tif end > len(set.All) {\n\t\t\tend = len(set.All)\n\t\t}\n\t\tbatch := set.All[i:end]\n\t\tbatchInClause, batchArgs := buildSQLInClause(batch)\n\n\t\tfor _, depTable := range []string{\"dependencies\", \"wisp_dependencies\"} {\n\t\t\trows, err := tx.QueryContext(ctx,\n\t\t\t\tfmt.Sprintf(`SELECT issue_id FROM %s WHERE %s`, depTable, depTargetIn(\"\", batchInClause)),\n\t\t\t\tbatchArgs...)\n\t\t\tif err != nil {\n\t\t\t\tif optionalBlockedTable(depTable) && isTableNotExistError(err) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\treturn nil, fmt.Errorf(\"count inbound dependencies from %s: %w\", depTable, err)\n\t\t\t}\n\t\t\tfor rows.Next() {\n\t\t\t\tvar issID string\n\t\t\t\tif err := rows.Scan(&issID); err != nil {\n\t\t\t\t\t_ = rows.Close()\n\t\t\t\t\treturn nil, fmt.Errorf(\"scan inbound dependency: %w\", err)\n\t\t\t\t}\n\t\t\t\tif !deletedSet[issID] {\n\t\t\t\t\tdepsCount++\n\t\t\t\t}\n\t\t\t}\n\t\t\t_ = rows.Close()\n\t\t\tif err := rows.Err(); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"iterate inbound dependencies from %s: %w\", depTable, err)\n\t\t\t}\n\t\t}\n\t}\n","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/delete.go#L237-L273","documentation":"DeleteResolvedSetInTx aborts when the query that finds inbound dependencies pointing at the batch (SELECT issue_id FROM <depTable> WHERE target IN (...)) fails. The table name is interpolated into the message. Tables marked optional are skipped when they don't exist, so this error means a non-optional dependency table query genuinely failed — connection loss, SQL error, or cancellation.","triggerScenarios":"Calling DeleteIssuesInTx/DeleteInTx where a dependency table query inside the batched dry-run scan fails: connection dropped mid-loop, invalid batch clause under a driver with different SQL quirks, or context cancellation.","commonSituations":"Custom/alternative storage drivers whose SQL dialect mismatches the generated IN-clause query; Dolt connection reset while scanning many batches; schema drift removing a required dependency table.","solutions":["Note the table name in the message and check that table's existence/integrity first.","Unwrap the driver error for the exact SQL failure (syntax, unknown table, connection).","Retry the delete on a fresh transaction if transient.","If using a non-Dolt driver, confirm it supports the dependency-table SQL emitted here or route through the driver interface fix."],"exampleFix":"// before\nerr := batchDelete(ctx, tx, ids)\n// after\nerr := batchDelete(ctx, tx, ids)\nif err != nil && strings.Contains(err.Error(), \"dependencies\") {\n    return fmt.Errorf(\"dependency table unreadable; run schema check: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"for _, tbl := range []string{\"dependencies\", \"wisp_dependencies\"} {\n    if err := checkTableExists(ctx, db, tbl); err != nil {\n        return fmt.Errorf(\"required table %s missing: %w\", tbl, err)\n    }\n}","typeGuard":null,"tryCatchPattern":"err := batchDelete(ctx, tx, ids)\nif err != nil {\n    var opErr *fmt.WrapError // inspect the named table in the message\n    m := tableFromInboundDepError(err)\n    if m != \"\" {\n        return fmt.Errorf(\"delete aborted at dependency table %q: %w\", m, err)\n    }\n    return err\n}","preventionTips":["Use only drivers that implement the full beads driver interface (storage boundary rule).","Test deletes against the driver in CI (see backend/conformance deleter_contract).","Keep transactions short so connection resets are unlikely mid-scan."],"tags":["go","storage","sql","dependencies","batch-delete"],"backgroundTag":"sql-count-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}