gastownhall/beads · error

iter comments %s: %w

Error message

iter comments %s: %w

What it means

This error is returned by collectComments in internal/workapi/detail.go when the initial call to DetailSource.IterComments fails, i.e. the comments iterator could not even be created for the issue id. It is raised before any rows are read, and BuildIssueDetails propagates it when DetailOptions.IncludeComments is true. Unlike the best-effort label/count fields, the opt-in comment stream is deliberately fail-hard: the caller asked for rows and gets a truthful error rather than a silently short list.

Source

Thrown at internal/workapi/detail.go:224

	var out []*types.IssueWithDependencyMetadata
	for iter.Next(ctx) {
		item := iter.Value()
		if item == nil {
			continue
		}
		out = append(out, shallowDep(item))
	}
	if err := iter.Err(); err != nil {
		return nil, fmt.Errorf("iter dependents %s: %w", id, err)
	}
	return out, nil
}

func collectComments(ctx context.Context, src DetailSource, id string, isWisp bool) ([]*types.Comment, error) {
	iter, err := src.IterComments(ctx, id, isWisp)
	if err != nil {
		return nil, fmt.Errorf("iter comments %s: %w", id, err)
	}
	defer iter.Close() //nolint:errcheck // read-only iterator

	var out []*types.Comment
	for iter.Next(ctx) {
		item := iter.Value()
		if item == nil {
			continue
		}
		// storage.Iter may reuse the pointer across Next calls, so a value
		// we keep has to be our own copy.
		comment := *item
		out = append(out, &comment)
	}
	if err := iter.Err(); err != nil {
		return nil, fmt.Errorf("iter comments %s: %w", id, err)
	}
	return out, nil

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the wrapped cause with errors.Is/errors.As to identify the underlying storage error
  2. Verify the database is reachable and the comments (and wisps) tables exist (e.g. `bd doctor`)
  3. Reconnect/reopen the store and retry
  4. Check that the isWisp routing matches how the issue was resolved (GetIssueOrWisp)

Example fix

// before
issue, isWisp, err := workapi.GetIssueOrWisp(ctx, src, id)
// ...use issue.ID and a hardcoded isWisp=false for a second detail call
details, err := workapi.BuildIssueDetails(ctx, src, issue, isWisp, opts)
// after
issue, isWisp, err := workapi.GetIssueOrWisp(ctx, src, id)
if err != nil {
    return err
}
// pass the resolved isWisp so comment queries route to the right table
details, err := workapi.BuildIssueDetails(ctx, src, issue, isWisp, opts)
if err != nil {
    return fmt.Errorf("comments for %s: %w", id, err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

if issue == nil || issue.ID == "" {
    return fmt.Errorf("cannot load comments: no issue id")
}
if err := ctx.Err(); err != nil {
    return fmt.Errorf("context already done: %w", err)
}

Type guard

func isIterOpenError(err error) bool {
    return err != nil && strings.HasPrefix(err.Error(), "iter comments ")
}

Try / catch

details, err := workapi.BuildIssueDetails(ctx, src, issue, isWisp, workapi.DetailOptions{IncludeComments: true})
if err != nil {
    if errors.Is(err, storage.ErrNotFound) {
        return fmt.Errorf("issue %s vanished between resolve and comment load", issue.ID)
    }
    return fmt.Errorf("comment stream could not start for %s: %w", issue.ID, err)
}

Prevention

When it happens

Trigger: Calling BuildIssueDetails with IncludeComments=true where src.IterComments(ctx, id, isWisp) returns a non-nil error on creation: the underlying comment table cannot be queried (database connection failure, table missing/corrupt, query preparation failure, invalid id routing between issue and wisp tables).

Common situations: Running `bd show` (or the HTTP detail handler) on an issue with comments while the Dolt database is unreachable or locked; a storage migration or version mismatch leaving the comments/wisps tables unavailable; a bug in the seam implementation misrouting a wisp id so the query targets a missing table.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/8555c9d426678d74. Report an issue: GitHub.