gastownhall/beads · error
dependency %s -> %s has invalid type
Error message
dependency %s -> %s has invalid type
What it means
The legacy row's type column does not map to a valid types.DependencyType, so the importer cannot construct a Dependency and aborts. Dependency types are a closed enum (e.g. blocks, parent-child, conditional-blocks) validated by DependencyType.IsValid().
Source
Thrown at internal/migration/legacysqlite/reader.go:926
return fmt.Errorf("dependency %s -> %s crosses ephemeral storage", id, to)
}
key := id + "\x00" + to
if seenDeps[key] {
return fmt.Errorf("multiple legacy dependencies for %s -> %s", id, to)
}
seenDeps[key] = true
created, e := parseTime(at)
if e != nil {
return e
}
if created.IsZero() {
return fmt.Errorf("dependency created_at is zero for %s -> %s", id, to)
}
if (metadata.Valid && metadata.String != "") || (thread.Valid && thread.String != "") {
return fmt.Errorf("dependency %s -> %s uses unsupported metadata or thread ID", id, to)
}
if !types.DependencyType(typ).IsValid() {
return fmt.Errorf("dependency %s -> %s has invalid type", id, to)
}
d := &types.Dependency{IssueID: id, DependsOnID: to, Type: types.DependencyType(typ), CreatedAt: created, CreatedBy: by, Metadata: nullString(metadata), ThreadID: nullString(thread)}
issue.Dependencies = append(issue.Dependencies, d)
return nil
}
func loadComments(ctx context.Context, db *sql.Tx, byID map[string]*types.Issue) error {
comments, err := db.QueryContext(ctx, "SELECT id,issue_id,author,text,CAST(created_at AS TEXT) FROM comments ORDER BY issue_id,created_at,id")
if err != nil {
return err
}
defer comments.Close()
type commentIdentity struct {
issueID, author, text string
createdAt time.Time
}
seenComments := make(map[commentIdentity]int64)
for comments.Next() {View on GitHub (pinned to 71377f2769)
Solutions
- Inspect offending rows: SELECT * FROM dependencies WHERE type NOT IN (<valid types>) and fix them to a valid type
- Update unknown types to their modern equivalents (e.g. legacy 'related' -> appropriate valid type) in the legacy DB
- Remove rows with unrecoverable type values and recreate the dependencies in bd after migration
Example fix
-- before -- type = 'watch' UPDATE dependencies SET type = 'blocks' WHERE type = 'watch'; -- after: type is a valid DependencyType
Defensive patterns
Strategy: validation
Validate before calling
const VALID = new Set(['blocks','conditional-blocks','parent-child','related']);
for (const d of legacyDeps) {
if (!VALID.has(String(d.type)))
throw new Error(`invalid dependency type '${d.type}' on ${d.issue_id} -> ${d.depends_on_id}`);
} Type guard
function hasValidType(d, validTypes) {
return validTypes.some(t => String(d.type) === t);
} Try / catch
try { migrateLegacySQLite(dbPath) } catch (e) {
if (e.message.includes('has invalid type')) {
fixUnknownDepTypes(dbPath); // map legacy names -> valid types
retry();
} else throw e;
} Prevention
- Verify dependency type values against the current DependencyType enum before import
- Add a CHECK constraint on the legacy type column
- Audit type values with GROUP BY type before migrating
When it happens
Trigger: Legacy SQLite dependency rows whose type value is not one of the recognized dependency type strings/ints — e.g. from an even older schema, corrupted data, or hand-edited SQL.
Common situations: Restored or partially-migrated legacy databases; rows inserted by tooling that used free-form type strings; version mismatch where legacy type names were later renamed.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- sealed legacy SQLite database does not match source fingerpr
- sealed legacy SQLite WAL does not match source fingerprint
- legacy SQLite source changed while sealing
- legacy SQLite source %q must not be a symlink
- legacy SQLite source %q must be a regular file
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/f4f26547c17e74e6.
Report an issue: GitHub.