gastownhall/beads · error
failed to clear ephemeral flag on root %s: %w
Error message
failed to clear ephemeral flag on root %s: %w
What it means
After closing a wisp root, squash clears its ephemeral flag (sets wisp=false) so the closed root stops being re-emitted by wisp-table export cycles. If w.UpdateIssue fails, the error is wrapped as 'failed to clear ephemeral flag on root %s: %w' and the transaction rolls back.
Source
Thrown at cmd/bd/mol_squash.go:330
// Delete ephemeral children within the same transaction
if !keepChildren {
for _, id := range childIDs {
if err := w.DeleteIssue(ctx, id, actorName); err != nil {
return nil, fmt.Errorf("failed to delete child %s: %w", id, err)
}
result.DeletedCount++
}
}
// Auto-close the root if it's a wisp — squash completes the molecule lifecycle
if root.Ephemeral {
reason := fmt.Sprintf("Squashed: %d steps → digest %s", len(children), result.DigestID)
if err := w.CloseIssue(ctx, root.ID, reason, actorName); err != nil {
return nil, fmt.Errorf("failed to close wisp root %s: %w", root.ID, err)
}
// Clear ephemeral so the closed root stops being re-emitted by every wisp-table export cycle.
if err := w.UpdateIssue(ctx, root.ID, map[string]interface{}{"wisp": false}, actorName); err != nil {
return nil, fmt.Errorf("failed to clear ephemeral flag on root %s: %w", root.ID, err)
}
result.WispSquash = true
}
return result, nil
}
func init() {
molSquashCmd.Flags().Bool("dry-run", false, "Preview what would be squashed")
molSquashCmd.Flags().Bool("keep-children", false, "Don't delete ephemeral children after squash")
molSquashCmd.Flags().String("summary", "", "Agent-provided summary (bypasses auto-generation)")
molCmd.AddCommand(molSquashCmd)
}
View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the wrapped cause; run any pending migrations and bd doctor to verify the wisp field exists
- Stop competing bd processes/syncs, then retry the squash
- If schema mismatch persists, back up and re-migrate the database before squashing
Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure schema supports the wisp field before squashing ephemeral roots
if root.Ephemeral && !schemaHasWispField() {
return fmt.Errorf("database schema outdated; run migrations")
} Type guard
func isWisp(i *types.Issue) bool { return i != nil && i.Ephemeral } Try / catch
err := squashMolecule(ctx, s, root, children, keep, summary, actor)
if err != nil {
if strings.Contains(err.Error(), "failed to clear ephemeral flag") {
log.Printf("flag clear failed; rerun migrations: %v", errors.Unwrap(err))
}
return err
} Prevention
- Run migrations/bd doctor after every bd upgrade
- Avoid exporting wisps while a squash transaction is open
- Back up the database before schema-affecting operations
When it happens
Trigger: Squashing an ephemeral root when the flag-clearing update fails: storage write error, database lock, schema mismatch on the wisp/ephemeral column, or root deleted concurrently.
Common situations: Older database schema lacking the wisp field; export/sync process holding locks; interrupted upgrade leaving partial wisp metadata.
Related errors
- failed to close wisp root %s: %w
- node %q: updating metadata refs: %w
- determining wisp status for %s: %w
- failed to create digest issue: %w
- failed to link digest to root: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/c61b5885fd199c14.
Report an issue: GitHub.