apache/answer · error

read email input failed: %w

Error message

read email input failed: %w

What it means

ResetPassword wraps a failure from reading the user's email from stdin via bufio.Reader.ReadString('\n') when opts.Email was empty. This happens in interactive prompts; typically it means stdin was closed or an I/O error occurred.

Source

Thrown at internal/cli/reset_password.go:108

	dataData, dataCleanup, err := data.NewData(db, cache)
	if err != nil {
		return fmt.Errorf("initialize data layer failed: %w", err)
	}
	defer dataCleanup()

	userRepo := user.NewUserRepo(dataData)
	authRepo := auth.NewAuthRepo(dataData)
	apiKeyRepo := api_key.NewAPIKeyRepo(dataData)
	authSvc := authService.NewAuthService(authRepo, apiKeyRepo)

	email := strings.TrimSpace(opts.Email)
	if email == "" {
		reader := bufio.NewReader(os.Stdin)
		fmt.Print("Please input user email: ")
		emailInput, err := reader.ReadString('\n')
		if err != nil {
			return fmt.Errorf("read email input failed: %w", err)
		}
		email = strings.TrimSpace(emailInput)
	}

	userInfo, exist, err := userRepo.GetByEmail(ctx, email)
	if err != nil {
		return fmt.Errorf("query user failed: %w", err)
	}
	if !exist {
		return fmt.Errorf("user not found: %s", email)
	}

	fmt.Printf("You are going to reset password for user: %s\n", email)

	password := strings.TrimSpace(opts.Password)

	if password != "" {
		printWarning("Passing password via command line may be recorded in shell history")

View on GitHub (pinned to 3b9f137061)

Solutions

  1. Pass the email explicitly via options (opts.Email) instead of relying on stdin.
  2. Run interactively with a real TTY (e.g. docker run -it).
  3. If piping input, ensure the email line is present on stdin.

Example fix

// before
_ = cli.ResetPassword(ctx, dataDir, &cli.ResetPasswordOptions{})
// after
_ = cli.ResetPassword(ctx, dataDir, &cli.ResetPasswordOptions{Email: "admin@example.com"})
Defensive patterns

Strategy: validation

Validate before calling

if opts.Email == "" && term.IsTerminal(int(os.Stdin.Fd())) == false {
    return fmt.Errorf("non-interactive session: pass --email")
}

Try / catch

if err := cli.ResetPassword(ctx, dataDir, &ResetPasswordOptions{}); err != nil {
    if strings.Contains(err.Error(), "read email input failed") {
        log.Fatalf("stdin unavailable; pass --email explicitly: %v", err)
    }
}

Prevention

When it happens

Trigger: ResetPassword invoked without --email (or with empty opts.Email) in a non-interactive context — piped input exhausted, stdin closed, no TTY.

Common situations: Running the CLI in CI/scripts without passing the email flag, docker run without -i, output piped so stdin is /dev/null.

Related errors


AI-assisted analysis of apache/answer@3b9f137061 (2026-09-05). Data as JSON: /api/errors/cd8712da81aa7e50. Report an issue: GitHub.