gastownhall/beads · error
reading confirmation: %w
Error message
reading confirmation: %w
What it means
This wraps a failure reading the y/n confirmation answer from stdin during `bd migrate`'s interactive apply prompt. ReadString('\n') fails if stdin is closed (EOF) or is not a readable stream. The migration aborts without applying anything.
Source
Thrown at cmd/bd/migrate_hooks_apply.go:445
func filesEqual(pathA, pathB string) (bool, error) {
a, err := os.ReadFile(pathA) // #nosec G304 -- compared paths come from deterministic migration operations
if err != nil {
return false, err
}
b, err := os.ReadFile(pathB) // #nosec G304 -- compared paths come from deterministic migration operations
if err != nil {
return false, err
}
return bytes.Equal(a, b), nil
}
func confirmHookMigrationApply(totalOperations int) (bool, error) {
fmt.Printf("\nThis will apply %d hook migration operation(s). Continue? (Y/n): ", totalOperations)
reader := bufio.NewReader(os.Stdin)
response, err := reader.ReadString('\n')
if err != nil {
return false, fmt.Errorf("reading confirmation: %w", err)
}
response = strings.TrimSpace(strings.ToLower(response))
if response == "" || response == "y" || response == "yes" {
return true, nil
}
return false, nil
}
View on GitHub (pinned to 71377f2769)
Solutions
- Pipe the confirmation explicitly: `echo y | bd migrate` (empty line also confirms, so `< /dev/null` errors but `printf '\n' |` succeeds only if it returns cleanly).
- Run the command interactively in a terminal where stdin is open.
- Use a non-interactive flag if the migration supports one to skip the prompt entirely.
- In CI, gate the migration behind an explicit approval step that pipes the answer.
Example fix
// before $ bd migrate < /dev/null reading confirmation: EOF // after $ echo y | bd migrate
Defensive patterns
Strategy: try-catch
Validate before calling
stat, err := os.Stdin.Stat()
if err != nil || (stat.Mode()&os.ModeCharDevice) == 0 {
// stdin is not a TTY: provide input via pipe or use non-interactive mode
} Try / catch
if err != nil {
if errors.Is(err, io.EOF) || errors.Is(err, os.ErrClosed) {
// stdin closed: abort or default to confirm in non-interactive mode
return false, nil
}
return false, fmt.Errorf("reading confirmation: %w", err)
} Prevention
- Always pipe the answer when invoking bd from scripts/CI: echo y | bd migrate
- Detect non-TTY stdin and skip interactive prompts (use flags instead)
- Don't redirect stdin from empty files or closed pipes
When it happens
Trigger: Running `bd migrate` in a non-interactive context: stdin is /dev/null (CI, cron), a pipe that closed early, or stdin redirected from an empty/exhausted file, so ReadString returns io.EOF or another read error.
Common situations: CI pipelines and scripts that invoke bd without a TTY; `bd migrate < /dev/null`; piped invocation like `echo | bd migrate` where the pipe closes before input; nested tooling (agents) running bd headlessly.
Related errors
- failed to read confirmation: %w
- failed to read file: %w
- reading from stdin: %w
- --contributor requires interactive prompts and cannot be use
- --team requires interactive prompts and cannot be used with
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/9c59619c1467755a.
Report an issue: GitHub.