{"record":{"id":"b08020424bffd09e","repo":"gastownhall/beads","slug":"get-blocked-by-info-from-s-w","errorCode":null,"errorMessage":"get blocked-by info from %s: %w","messagePattern":"get blocked-by info from (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/dependency_queries.go","lineNumber":619,"sourceCode":"\t\t\tplaceholders[i] = \"?\"\n\t\t\targs[i] = id\n\t\t}\n\t\tinClause := strings.Join(placeholders, \",\")\n\n\t\t// Query: \"blocked by\" — deps where issue_id is in our set.\n\t\t//nolint:gosec // G201: depTable is a caller-controlled constant.\n\t\tblockedByQuery := fmt.Sprintf(`\n\t\t\tSELECT d.issue_id, %s AS depends_on_id, d.type\n\t\t\tFROM %s d\n\t\t\tWHERE d.issue_id IN (%s) AND d.type IN ('blocks', 'parent-child')\n\t\t`, depTargetExpr(\"d\"), depTable, inClause)\n\n\t\trows, err := tx.QueryContext(ctx, blockedByQuery, args...)\n\t\tif err != nil {\n\t\t\tif optionalBlockedTable(depTable) && isTableNotExistError(err) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"get blocked-by info from %s: %w\", depTable, err)\n\t\t}\n\t\tvar depRows []blockingInfoRow\n\t\tvar blockerIDs []string\n\t\tfor rows.Next() {\n\t\t\tvar row blockingInfoRow\n\t\t\tif scanErr := rows.Scan(&row.issueID, &row.blockerID, &row.depType); scanErr != nil {\n\t\t\t\t_ = rows.Close()\n\t\t\t\treturn fmt.Errorf(\"get blocking info: scan blocked-by: %w\", scanErr)\n\t\t\t}\n\t\t\tdepRows = append(depRows, row)\n\t\t\tblockerIDs = append(blockerIDs, row.blockerID)\n\t\t}\n\t\t_ = rows.Close()\n\t\tif err := rows.Err(); err != nil {\n\t\t\treturn fmt.Errorf(\"get blocking info: blocked-by rows: %w\", err)\n\t\t}\n\n\t\tstatusByID, err := loadStatusByIDInTx(ctx, tx, blockerIDs)","sourceCodeStart":601,"sourceCodeEnd":637,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/dependency_queries.go#L601-L637","documentation":"Returned by queryBlockedByInfo (used by GetBlockingInfoForIssuesInTx) when the blocked-by SELECT against a dependency table fails at QueryContext time and the table is not an optional missing one. The %s names the failing table (dependencies or wisp_dependencies); %w wraps the driver error.","triggerScenarios":"Calling GetBlockingInfoForIssuesInTx when the dependencies table does not exist (fresh/corrupt DB — wisp_dependencies absence is tolerated, dependencies is not), SELECT permission is missing, the query fails against the backend dialect, or the connection is dead.","commonSituations":"Unmigrated/legacy database lacking the dependencies table; DB user lacking grants; Dolt server version mismatch; network failure to a remote backend.","solutions":["Examine the wrapped driver error to classify it (missing table vs permissions vs connection).","If the table is missing, run database initialization/migration so dependencies exists.","If permission denied, grant SELECT on the dependency tables to the connecting user.","If connection-related, verify the remote server is up and connection settings are correct.","Ensure client and server versions are compatible if the query itself is rejected."],"exampleFix":"// before: legacy DB without dependencies table\n// (bd fails: no such table: dependencies)\n\n// after: migrate to current schema\nbd doctor   // diagnose\nbd migrate  // or re-init to create dependencies table","handlingStrategy":"validation","validationCode":"// Go: ensure the non-optional dependencies table exists\nvar n int\nif err := tx.QueryRowContext(ctx,\n    \"SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_NAME = 'dependencies'\").Scan(&n); err != nil {\n    return err\n}\nif n == 0 {\n    return fmt.Errorf(\"dependencies table missing; run bd migrate\")\n}","typeGuard":"func isBlockedByTableError(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"get blocked-by info from\")\n}","tryCatchPattern":"blockedBy, blocks, parents, err := GetBlockingInfoForIssuesInTx(ctx, tx, ids)\nif err != nil && isBlockedByTableError(err) {\n    if strings.Contains(fmt.Sprint(errors.Unwrap(err)), \"no such table\") {\n        return runMigrations(ctx, tx) // then retry\n    }\n    return err\n}","preventionTips":["Initialize and migrate every new database before first use.","Keep dependencies table present; only wisp_dependencies is optional.","Grant the app user SELECT on all beads tables.","Run bd doctor as a preflight in scripts that touch the DB."],"tags":["database","sql","missing-table","query-failed"],"backgroundTag":"sql-no-such-table","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}