apache/answer · error

read email input failed

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.

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.

Appendix: 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)