{"record":{"id":"e063b26971353d6e","repo":"gastownhall/beads","slug":"query-dependency-targets-w","errorCode":null,"errorMessage":"query dependency targets: %w","messagePattern":"query dependency targets: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/dependencies.go","lineNumber":720,"sourceCode":"\t\tissueTarget sql.NullString\n\t\twispTarget  sql.NullString\n\t\texternal    sql.NullString\n\t\tdepType     string\n\t\tcreatedAt   sql.NullTime\n\t\tcreatedBy   sql.NullString\n\t\tmetadata    sql.NullString\n\t\tthreadID    sql.NullString\n\t}\n\n\trows := make([]depRow, 0)\n\t//nolint:gosec // table and column are hardcoded by callers.\n\tqueryRows, err := tx.QueryContext(ctx, fmt.Sprintf(`\n\t\tSELECT issue_id, depends_on_issue_id, depends_on_wisp_id, depends_on_external, type, created_at, created_by, metadata, thread_id\n\t\tFROM %s\n\t\tWHERE %s = ? OR (%s = ? AND depends_on_external IS NULL)\n\t`, table, column, DepTargetExpr), oldID, oldID)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"query dependency targets: %w\", err)\n\t}\n\tfor queryRows.Next() {\n\t\tvar row depRow\n\t\tif err := queryRows.Scan(&row.issueID, &row.issueTarget, &row.wispTarget, &row.external, &row.depType, &row.createdAt, &row.createdBy, &row.metadata, &row.threadID); err != nil {\n\t\t\t_ = queryRows.Close()\n\t\t\treturn fmt.Errorf(\"scan dependency target: %w\", err)\n\t\t}\n\t\tswitch column {\n\t\tcase \"depends_on_issue_id\":\n\t\t\trow.issueTarget = sql.NullString{String: newID, Valid: true}\n\t\t\trow.wispTarget = sql.NullString{}\n\t\t\trow.external = sql.NullString{}\n\t\tcase \"depends_on_wisp_id\":\n\t\t\trow.issueTarget = sql.NullString{}\n\t\t\trow.wispTarget = sql.NullString{String: newID, Valid: true}\n\t\t\trow.external = sql.NullString{}\n\t\tdefault:\n\t\t\t_ = queryRows.Close()","sourceCodeStart":702,"sourceCodeEnd":738,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/dependencies.go#L702-L738","documentation":"This error wraps failure of the SELECT in replaceDependencyTargetInTx, which loads every edge in `table` (dependencies or wisp_dependencies) whose typed target column equals oldID (or whose generated target expression equals oldID with no external target). The rows are reinserted with the new target because Dolt can leave the generated depends_on_id column stale after an FK-cascade update.","triggerScenarios":"UpdateIssueIDInTx or UpdateWispIDInTx rename, when tx.QueryContext on the parameterized SELECT over dependencies/wisp_dependencies fails: missing table/columns, aborted transaction, or dropped connection.","commonSituations":"Out-of-date schema missing depends_on_wisp_id / depends_on_external / thread_id columns; connection reset during a bulk rename; a previous statement in the same tx already failed.","solutions":["Read the wrapped driver error after the colon for the root cause","Migrate the schema so both dependencies and wisp_dependencies have all selected columns","Reconnect/retry; the transaction rolls back atomically on failure","If the tx is poisoned by an earlier error, fix that first"],"exampleFix":"// before: schema missing thread_id column\nSELECT ..., thread_id FROM wisp_dependencies WHERE depends_on_issue_id = ?\n-- Error: Unknown column 'thread_id' in 'field list'\n// after: bring schema current\nbd migrate && bd doctor","handlingStrategy":"try-catch","validationCode":"// Verify both target tables expose every selected column\nfor _, table := range []string{\"dependencies\", \"wisp_dependencies\"} {\n    var n int\n    db.Get(&n, `SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_NAME=? AND COLUMN_NAME IN\n      ('issue_id','depends_on_issue_id','depends_on_wisp_id','depends_on_external','type','created_at','created_by','metadata','thread_id')`, table)\n    if n < 9 { return fmt.Errorf(\"%s schema incomplete (%d/9); run bd migrate\", table, n) }\n}","typeGuard":null,"tryCatchPattern":"err := updateIssueOrWispID(tx, oldID, newID)\nif err != nil {\n    if isAbortedTxError(err) {\n        return fmt.Errorf(\"transaction already aborted by earlier statement; fix root cause before retrying: %w\", err)\n    }\n    return err\n}","preventionTips":["Migrate schema after every beads upgrade before running renames","Check bd doctor for schema drift across clones","Do not reuse a transaction after any failed statement","Confirm connectivity with a ping before long rename transactions"],"tags":["database","sql","query","transaction"],"backgroundTag":"sql-query-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}