gastownhall/beads · error

close reason is empty or default; provide a summary of what

Error message

close reason is empty or default; provide a summary of what was done

What it means

ValidateCloseReason refuses close reasons that are empty or exactly the word "closed" (case-insensitive). The library requires a human-meaningful summary of what was done when closing an issue, because validation.on-close config enforces close-reason quality. A bare or default reason carries no audit value.

Source

Thrown at internal/validation/template.go:208

		heading := strings.ToLower(strings.TrimPrefix(m.Heading, "## "))
		if heading == "acceptance criteria" || heading == "success criteria" {
			continue // satisfied by the dedicated field
		}
		remaining = append(remaining, m)
	}
	if len(remaining) == 0 {
		return nil
	}
	templateErr.Missing = remaining
	return templateErr
}

// ValidateCloseReason checks if a close reason meets minimum quality standards.
// Returns nil if the reason is acceptable. Used by validation.on-close config.
func ValidateCloseReason(reason string) error {
	reason = strings.TrimSpace(reason)
	if reason == "" || strings.EqualFold(reason, "closed") {
		return fmt.Errorf("close reason is empty or default; provide a summary of what was done")
	}
	if len(reason) < 20 {
		return fmt.Errorf("close reason is terse (%d chars); aim for 20+ characters describing what was done", len(reason))
	}
	return nil
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Pass a descriptive reason with the close command, e.g. bd close bd-42 --reason "Fixed by normalizing prefix in bootstrap; covered by tests"
  2. If closing many issues in a script, template a reason that names the commit or change
  3. Remove or relax the validation.on-close config only if your team genuinely does not require close summaries

Example fix

// before
bd close bd-42 --reason "closed"
// after
bd close bd-42 --reason "Fixed flaky TestSync by retrying dolt push; see commit ab12cd"
Defensive patterns

Strategy: validation

Validate before calling

func validCloseReason(r string) bool {
    r = strings.TrimSpace(r)
    return r != "" && !strings.EqualFold(r, "closed") && len(r) >= 20
}
// call: if !validCloseReason(reason) { reason = buildDescriptiveReason() }

Try / catch

if err := validation.ValidateCloseReason(reason); err != nil {
    if strings.Contains(err.Error(), "empty or default") { reason = promptForReason() }
    return err
}

Prevention

When it happens

Trigger: Calling bd close (or any path that invokes ValidateCloseReason via validation.on-close) with an empty --reason flag, whitespace-only input, or the literal string "closed"/"Closed".

Common situations: Scripts and agents closing issues programmatically with bd close without --reason; interactive users accepting a default close message; CI automations that forgot the reason field.

Related errors


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