gastownhall/beads · error
reading types.custom: %w
Error message
reading types.custom: %w
What it means
flattenUnregisteredIssueTypes determines which issue types in a cloned subgraph are unknown, by reading the registered custom types from config key 'types.custom' via s.GetConfig. If that read fails, the function refuses to assume 'nothing is registered' (which would silently flatten legitimately registered custom types) and instead throws 'reading types.custom: %w'. This is a deliberate fail-loud guard against data loss.
Source
Thrown at cmd/bd/template.go:609
t := issue.IssueType
if t == "" || t.IsBuiltIn() {
continue
}
unknown[t] = true
}
if len(unknown) == 0 {
return nil
}
// Match insert validation's sources: the types.custom config value
// (kept in step with the custom_types table by SyncConfigTables)
// overlaid with config.yaml-declared types. Read through s so a
// transaction-bound caller sees in-transaction registration.
existing, err := s.GetConfig(ctx, "types.custom")
if err != nil {
// Don't degrade to "nothing registered": a transient read failure
// would silently flatten types the operator did register.
return fmt.Errorf("reading types.custom: %w", err)
}
for _, t := range issueops.ParseTypesConfigValue(existing) {
delete(unknown, types.IssueType(t))
}
for _, t := range config.GetCustomTypesFromYAML() {
delete(unknown, types.IssueType(t))
}
if len(unknown) == 0 {
return nil
}
names := make([]string, 0, len(unknown))
for t := range unknown {
names = append(names, string(t))
}
sort.Strings(names)
WarnError("flattening unregistered issue type(s) to task (epic for steps with children): %s (register with bd config set types.custom to keep them)", strings.Join(names, ", "))
View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped error from errors.Unwrap and fix the underlying config-read failure.
- Run `bd doctor` to check storage/config health.
- Retry the clone once storage is responsive.
- Declare the custom types in config.yaml so cloning works even when custom-type registration must be re-created.
Example fix
// config.yaml
issue-types:
custom:
- molecule
- gate
// ensures types resolve even if types.custom registration needs rebuild Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := s.GetConfig(ctx, "types.custom"); err != nil {
return fmt.Errorf("cannot read registered types, aborting clone: %w", err)
} Try / catch
err := flattenUnregisteredIssueTypes(ctx, tx, issues)
if err != nil && strings.HasPrefix(err.Error(), "reading types.custom") {
// do NOT proceed: proceeding would flatten registered custom types
return err
} Prevention
- Keep the config table healthy; run `bd doctor` after storage errors.
- Declare custom types in config.yaml as a resilient fallback.
- Avoid interrupting `bd` mid-transaction.
When it happens
Trigger: Calling cloneSubgraphInto (or flattenUnregisteredIssueTypes directly, as in TestFlattenUnregisteredIssueTypes) when s.GetConfig(ctx, "types.custom") errors — transaction-bound reads failing, storage driver errors, or config store corruption.
Common situations: Dolt storage read failure mid-transaction; a broken or unreadable config table after an interrupted migration; embedded driver I/O errors.
Related errors
- failed to set routing.contributor: %w
- failed to set sync branch: %w
- failed to enable team mode: %w
- failed to set team sync branch: %w
- database not available
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/d46f1fb9b5d725ca.
Report an issue: GitHub.