gastownhall/beads · error
checking custom types: %w
Error message
checking custom types: %w
What it means
Wraps failures from flattenUnregisteredIssueTypes inside the cook --persist transaction. That helper checks each generated step's issue type against registered custom types and flattens unregistered ones to `task`; if the check itself fails (e.g. it cannot read the configured issue types), the whole cook --persist transaction is rolled back under this message.
Source
Thrown at cmd/bd/cook.go:908
// Use labelHandler to extract labels for separate DB storage
collectSteps(f.Steps, protoID, idMapping, nil, &issues, &deps, func(issueID, label string) {
labels = append(labels, struct{ issueID, label string }{issueID, label})
})
// Collect dependencies from depends_on
for _, step := range f.Steps {
collectDependencies(step, idMapping, &deps)
}
// Create issues, labels, and dependencies in a single atomic transaction.
// This prevents orphaned issues if label/dependency creation fails.
err := transact(ctx, s, fmt.Sprintf("bd: cook formula %s", protoID), func(tx storage.Transaction) error {
// Flatten unregistered step types to task (with a warning) before
// inserting, mirroring cloneSubgraphInto (pour). Without this,
// PrepareIssueForInsert rejects them with "invalid issue type" and
// the whole cook --persist transaction rolls back.
if err := flattenUnregisteredIssueTypes(ctx, storeMolWriter{DoltStorage: s, tx: tx}, issues, deps); err != nil {
return fmt.Errorf("checking custom types: %w", err)
}
// Create all issues
if err := tx.CreateIssues(ctx, issues, actor); err != nil {
return fmt.Errorf("failed to create issues: %w", err)
}
// Add labels
for _, l := range labels {
if err := tx.AddLabel(ctx, l.issueID, l.label, actor); err != nil {
return fmt.Errorf("failed to add label %s to %s: %w", l.label, l.issueID, err)
}
}
// Add dependencies
for _, dep := range deps {
if err := tx.AddDependency(ctx, dep, actor); err != nil {
return fmt.Errorf("failed to create dependency: %w", err)View on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped cause; if config read failed, repair or regenerate the .beads configuration defining issue types
- Register the custom issue types your formula steps use (or rely on flattening to task) so the check passes
- Verify database/config readability and permissions inside the transaction
- Re-run `bd cook --persist` after fixing; the transaction is atomic so no partial data remains
Defensive patterns
Strategy: try-catch
Try / catch
err := transact(ctx, s, "bd: cook formula "+protoID, func(tx storage.Transaction) error {
if ferr := flattenUnregisteredIssueTypes(ctx, w, issues, deps); ferr != nil {
return fmt.Errorf("checking custom types: %w", ferr)
}
return nil
})
if err != nil && strings.Contains(err.Error(), "checking custom types") {
log.Printf("type-flatten failed, transaction rolled back: %v", errors.Unwrap(err))
// repair config/issue types, then re-run cook --persist
} Prevention
- Keep the .beads config defining issue types readable and valid
- Register custom types your formulas emit, or expect flattening to task
- Run `bd doctor` if config reads start failing inside transactions
- Treat cook --persist as atomic: a rollback means simply fix and re-run
When it happens
Trigger: cookFormula's transaction invokes flattenUnregisteredIssueTypes with storeMolWriter and the generated issues/deps; the helper errors when it cannot read registered issue types from config or fails validating/rewriting issue types on the generated issues.
Common situations: Corrupt or unreadable .beads/config listing issue types; custom type definitions removed while formulas still emit those step types; transaction/IO error reading config inside the Dolt transaction.
Related errors
- failed to create issues: %w
- failed to add label %s to %s: %w
- ErrTransaction
- line %d (%s): %w
- proto %s already exists (use --force to replace)
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/f0ad2c52ae587cfb.
Report an issue: GitHub.