gastownhall/beads · error
legacy SQLite issue %s: %w
Error message
legacy SQLite issue %s: %w
What it means
During loadIssues, each scanned legacy issue is validated by issue.Validate(); any validation failure is wrapped as 'legacy SQLite issue <id>: <reason>'. This means the legacy row's data violates issue invariants (e.g. missing/invalid status, bad priority, empty ID, invalid field values), so the issue cannot be safely imported.
Source
Thrown at internal/migration/legacysqlite/reader.go:481
}
if err := checkCurrentInts(
currentInt{"issue estimated_minutes", x.estimatedMinutes},
currentInt{"issue compaction_level", x.compactionLevel},
currentInt{"issue original_size", x.originalSize},
); err != nil {
return err
}
if err := x.applyCanonicalTimestamps(issue); err != nil {
return err
}
if err := checkRequiredScalars(issue); err != nil {
return err
}
if err := x.checkRemovedFields(issue); err != nil {
return err
}
if err := issue.Validate(); err != nil {
return fmt.Errorf("legacy SQLite issue %s: %w", issue.ID, err)
}
return nil
}
// applyOptionalTimestamps parses the legacy issue's optional timestamp columns
// (closed_at, compacted_at, due_at, defer_until) and assigns them to issue.
func (x legacyExtras) applyOptionalTimestamps(issue *types.Issue) error {
var err error
if issue.ClosedAt, err = parseOptionalTime("closed_at", x.closedAt); err != nil {
return fmt.Errorf("legacy SQLite issue %s: %w", issue.ID, err)
}
if issue.CompactedAt, err = parseOptionalTime("compacted_at", x.compactedAt); err != nil {
return fmt.Errorf("legacy SQLite issue %s: %w", issue.ID, err)
}
if issue.DueAt, err = parseOptionalTime("due_at", x.dueAt); err != nil {
return fmt.Errorf("legacy SQLite issue %s: %w", issue.ID, err)
}
if issue.DeferUntil, err = parseOptionalTime("defer_until", x.deferUntil); err != nil {View on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped inner message to see which field failed validation, then fix that row's column values in the legacy DB (e.g. normalize status/priority to current enum values).
- Identify the offending issue ID from the error and repair or delete the row, then re-run migration.
- Check whether the legacy DB predates a schema/vocabulary change and run any needed upgrade steps before migrating.
- Export the row, validate it offline, and re-import after correction.
Example fix
-- before (row fails validation)
UPDATE issues SET status='in_progress' WHERE id='bd-42';
-- after (canonical enum value)
UPDATE issues SET status='in_progress' WHERE id='bd-42' AND status IN ('open','in_progress','closed'); Defensive patterns
Strategy: validation
Validate before calling
// before migration, check enum values
rows, _ := db.Query(`SELECT id FROM issues WHERE status NOT IN ('open','in_progress','closed') OR priority NOT IN (0,1,2,3,4)`)
// fix reported rows first Try / catch
if err := loadIssues(...); err != nil {
var issueID string
if _, scanErr := fmt.Sscanf(err.Error(), "legacy SQLite issue %s", &issueID); scanErr == nil {
// inspect and repair that row in the legacy DB
}
return err
} Prevention
- Run a pre-migration audit query for invalid enum values in issues.
- Keep legacy DBs on the beads version that wrote them until migration.
- Never INSERT into legacy issues tables with raw SQL.
- Validate a copy of the DB first; migrate only after verify passes.
When it happens
Trigger: Migrating a legacy SQLite DB where an issues row has field values that fail types.Issue.Validate — for example an unknown status enum value, invalid priority, out-of-range or malformed fields.
Common situations: Legacy DBs written by old beads versions whose status/priority vocabularies changed; rows corrupted by manual SQL edits; data imported from another tracker with non-canonical enum values; half-finished writes in the legacy DB.
Related errors
- legacy SQLite issue %s has invalid metadata JSON
- issue %s waiters: invalid JSON
- blocking dependency %s -> %s conflicts with parent-child hie
- sealed legacy SQLite database does not match source fingerpr
- sealed legacy SQLite WAL does not match source fingerprint
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/42db2d0d53ee37ad.
Report an issue: GitHub.