gastownhall/beads · error
count %s orphans: %w
Error message
count %s orphans: %w
What it means
For each spec'd FK whose constraint is missing, scanSeveredCloneLocalFKs counts orphaned rows via a generated NOT EXISTS query (identifiers come from the fixed CloneLocalFKs spec, not user input). If that count query fails, the scan returns this wrapped error instead of a SeveredCloneLocalFK entry.
Source
Thrown at cmd/bd/doctor/fix/clone_local_fks.go:102
if err := db.QueryRow(
`SELECT COUNT(*) FROM information_schema.TABLE_CONSTRAINTS
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND CONSTRAINT_NAME = ? AND CONSTRAINT_TYPE = 'FOREIGN KEY'`,
fk.Table, fk.Constraint,
).Scan(&constraints); err != nil {
return nil, fmt.Errorf("check %s.%s: %w", fk.Table, fk.Constraint, err)
}
if constraints > 0 {
continue
}
var orphans int
//nolint:gosec // G201: identifiers come from the fixed CloneLocalFKs spec above, not user input.
orphanCount := fmt.Sprintf(
`SELECT COUNT(*) FROM %s t WHERE t.%s IS NOT NULL AND NOT EXISTS (SELECT 1 FROM %s r WHERE r.%s = t.%s)`,
fk.Table, fk.Column, fk.RefTable, fk.RefColumn, fk.Column,
)
if err := db.QueryRow(orphanCount).Scan(&orphans); err != nil {
return nil, fmt.Errorf("count %s orphans: %w", fk.Table, err)
}
severed = append(severed, SeveredCloneLocalFK{CloneLocalFK: fk, Orphans: orphans})
}
return severed, nil
}
// CloneLocalFKEnforcement re-links severed clone-local FKs: for each missing
// constraint it deletes the orphaned rows that accumulated while enforcement
// was off (ADD CONSTRAINT validates existing rows, so they must go first),
// then re-adds the constraint in place. Verified on dolt 2.2.2: the re-added
// FK resolves against the current tracked root and enforces again.
func CloneLocalFKEnforcement(path string, verbose bool) error {
beadsDir, err := resolvedWorkspaceBeadsDir(path)
if err != nil {
return err
}
View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped driver error and re-run `bd doctor` after the storage issue is resolved.
- Verify the actual schema matches the CloneLocalFKs spec (table/column names) after any manual migration.
- Check for disk/lock issues in the .beads Dolt store and free space or clear locks.
- Reduce scan size by repairing one workspace at a time if timeouts are the cause.
Defensive patterns
Strategy: validation
Validate before calling
// Confirm spec'd tables/columns still exist before the orphan count runs: rows, _ := db.Query(`SELECT TABLE_NAME, COLUMN_NAME FROM information_schema.COLUMNS`) // compare against CloneLocalFKs entries; mismatch = schema drift to fix first
Try / catch
severed, err := ScanSeveredCloneLocalFKs(ctx, db)
if err != nil && strings.Contains(err.Error(), "count") {
// orphan-count failure: fix schema drift or storage, then rescan
return err
} Prevention
- Don't manually rename FK tables/columns that the CloneLocalFKs spec expects
- Check disk space before large orphan scans
- Run scans on a quiescent database (no concurrent writes)
- Re-run doctor after failures; the scan is read-only and safe to repeat
When it happens
Trigger: The dynamically built orphan-count SELECT fails in scanSeveredCloneLocalFKs (cmd/bd/doctor/fix/clone_local_fks.go:102) — typically a storage/driver failure mid-scan or a table that exists but cannot be read.
Common situations: Large orphan scans hitting storage timeouts, a partially migrated schema where fk.Column/fk.RefTable no longer match the actual tables, or Dolt read errors on a cloned repo.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/4384ba1b4a7c163c.
Report an issue: GitHub.