gastownhall/beads · error
step %s not found
Error message
step %s not found
What it means
The molecule step-advance transaction looks up the step issue by ID inside a Dolt transaction and requires it to exist. When `tx.GetIssue` returns nil (the ID does not correspond to any issue), the port layer converts that into a formatted `step %s not found` error so the caller knows the molecule step ID was wrong.
Source
Thrown at cmd/bd/mol_port.go:107
// store, which opens a second pool connection — a deadlock when
// MaxOpenConns=1 and the transaction already holds the only one. It also
// keeps the read consistent with any config written earlier in the same
// transaction rather than seeing the last committed value.
func (w storeMolWriter) GetConfig(ctx context.Context, key string) (string, error) {
if w.tx != nil {
return w.tx.GetConfig(ctx, key)
}
return w.DoltStorage.GetConfig(ctx, key)
}
func (w storeMolWriter) ClaimStepIfOpen(ctx context.Context, id, actor string) error {
return w.DoltStorage.RunInTransaction(ctx, fmt.Sprintf("bd: advance to step %s", id), func(tx storage.Transaction) error {
current, err := tx.GetIssue(ctx, id)
if err != nil {
return err
}
if current == nil {
return fmt.Errorf("step %s not found", id)
}
if current.Status != types.StatusOpen {
return fmt.Errorf("step %s already claimed (status: %s)", id, current.Status)
}
return tx.UpdateIssue(ctx, id, map[string]interface{}{"status": types.StatusInProgress}, actor)
})
}
func newStandaloneStoreMolWriter(store storage.DoltStorage) storeMolWriter {
return storeMolWriter{DoltStorage: store}
}
type uowMolReader struct {
uw uow.UnitOfWork
}
func (r uowMolReader) GetIssue(ctx context.Context, id string) (*types.Issue, error) {
issue, isWisp, rerr := workapi.GetIssueOrWisp(ctx, workapi.NewUOWDetailSource(r.uw), id)View on GitHub (pinned to 71377f2769)
Solutions
- Verify the step ID with `bd show <id>` (or `bd list`) and correct any typo.
- List the molecule's actual steps (`bd mol progress <molecule>`) and use one of those IDs.
- Confirm you are operating on the same database/workspace that contains the molecule.
Example fix
// before err := writer.AdvanceToStep(ctx, "bd-9999", actor) // id typo // after err := writer.AdvanceToStep(ctx, "bd-1234", actor) // verified step id
Defensive patterns
Strategy: validation
Validate before calling
// shell: confirm the step exists before advancing
bd show "$STEP_ID" --json >/dev/null 2>&1 || { echo "step $STEP_ID does not exist"; exit 1; }
# then invoke the advance/claim step via your mol workflow Type guard
func stepExists(ctx context.Context, r MolReader, id string) bool {
iss, err := r.GetIssue(ctx, id)
return err == nil && iss != nil
} Try / catch
if err := advance(ctx, stepID, actor); err != nil && strings.Contains(err.Error(), "not found") {
return fmt.Errorf("step id %q invalid: %w", stepID, err)
} Prevention
- Pull step IDs from `bd mol progress <molecule>` output rather than hardcoding them.
- Re-verify IDs after burns, wisp flushes, or database rebuilds.
- Confirm the working directory/database matches where the molecule lives.
When it happens
Trigger: Calling the molecule port's advance/claim operation with an issue ID that does not exist in the database — e.g. a typo'd step ID, an ID from another database, or a deleted/wisp-routed issue. `GetIssue` returns nil inside the `RunInTransaction` callback and the error is raised.
Common situations: Copy-pasting an ID with a typo; referencing a step that was closed and cleaned up; pointing at a different workspace/database than the one containing the molecule; stale scripts holding IDs from a re-created molecule.
Related errors
- issue %s not found
- resolving ID %s: no issue found matching %q
- resolving --deps target %q: %w
- parent issue %s not found
- resolving issue ID %q: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/71d6f778b18dc7f2.
Report an issue: GitHub.