gohugoio/hugo · warning

aborted

Error message

aborted

What it means

When deployment.confirm is enabled and the run is not a dry run, Hugo prints the diff summary and prompts 'Continue? (Y/n)'. Any answer that is not y/Y (or an empty/failed stdin read) causes Deploy to return this 'aborted' error. It is a user-initiated cancellation, not a system fault.

Solutions

  1. Answer 'y' at the prompt to proceed with the deploy.
  2. Set confirm=false in config (or --confirm=false) to skip the prompt in automation.
  3. Use --dryRun to preview changes without prompting.

Example fix

// before
hugo deploy   # then type 'n'
// after
hugo deploy   # then type 'y'
Defensive patterns

Strategy: try-catch

Validate before calling

// For automation, disable confirm so no prompt can abort
viper.Set("deployment.confirm", false)

Try / catch

if err := deployer.Deploy(ctx); err != nil {
    if err.Error() == "aborted" {
        // user declined; treat as non-fatal cancellation
        return nil
    }
    return err
}

Prevention

When it happens

Trigger: `hugo deploy` with confirm enabled, where the user types n, anything other than y, or stdin is closed/empty (e.g. piped input).

Common situations: Reviewing the upload/delete diff and declining; non-interactive shells or CI piping empty stdin into an interactive prompt.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/025014151dd910ea. Report an issue: GitHub.

Appendix: source

Thrown at deploy/deploy.go:180

	if len(uploads)+len(deletes) == 0 {
		if !d.quiet {
			d.logger.Println("No changes required.")
		}
		return nil
	}
	if !d.quiet {
		d.logger.Println(summarizeChanges(uploads, deletes))
	}

	// Ask for confirmation before proceeding.
	if d.cfg.Confirm && !d.cfg.DryRun {
		fmt.Printf("Continue? (Y/n) ")
		var confirm string
		if _, err := fmt.Scanln(&confirm); err != nil {
			return err
		}
		if confirm != "" && confirm[0] != 'y' && confirm[0] != 'Y' {
			return errors.New("aborted")
		}
	}

	// Order the uploads. They are organized in groups; all uploads in a group
	// must be complete before moving on to the next group.
	uploadGroups := applyOrdering(d.cfg.Ordering, uploads)

	nParallel := d.cfg.Workers
	var errs []error
	var errMu sync.Mutex // protects errs

	for _, uploads := range uploadGroups {
		// Short-circuit for an empty group.
		if len(uploads) == 0 {
			continue
		}

		// Within the group, apply uploads in parallel.

View on GitHub (pinned to 52c9bd7908)