docker/cli · warning

hook template contains too many messages

Error message

hook template contains too many messages (%d): maximum is %d

What it means

Thrown by hooks.ParseTemplate after template expansion when the rendered output contains more than maxMessages (10) newline-separated messages. Hook messages are appended as next-steps hints; a runaway template emitting many lines would flood the output, so a hard cap of 10 is enforced.

Solutions

  1. Reduce the template output to at most 10 newline-separated messages.
  2. Replace iteration over large lists with a summarized single message.
  3. Move long-form content out of the hook (e.g. link to docs) instead of printing it.
Defensive patterns

Strategy: validation

Validate before calling

// after expanding the template yourself, count newlines
if strings.Count(expanded, "\n") > 10 {
    return fmt.Errorf("template yields %d messages; max is 10", strings.Count(expanded, "\n"))
}

Try / catch

msgs, err := hooks.ParseTemplate(tpl, cmd)
if err != nil {
    // degrade gracefully, skip next-steps
    return nil
}

Prevention

When it happens

Trigger: A plugin hook template whose expansion produces >10 lines, e.g. iterating over many items or embedding a multi-line blob. The check counts newlines in the post-expansion string.

Common situations: A hook template that ranges over a large list, or includes a literal multi-line document. Bumping content during plugin development can cross the 10-line threshold unexpectedly.

Related errors


AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07). Data as JSON: /api/errors/94c914aa35b53f6d. Report an issue: GitHub.

Appendix: source

Thrown at cli-plugins/hooks/template.go:44

			"flagValue": msgContext.flagValue,
			"argValue":  msgContext.argValue,

			// kept for backward-compatibility with old templates.
			"flag": func(_ any, flagName string) (string, error) { return msgContext.flagValue(flagName) },
			"arg":  func(_ any, i int) (string, error) { return msgContext.argValue(i) },
		}).Parse(hookTemplate)
		if err != nil {
			return nil, err
		}
		var b bytes.Buffer
		err = tmpl.Execute(&b, msgContext)
		if err != nil {
			return nil, err
		}
		out = b.String()
	}
	if n := strings.Count(out, "\n"); n > maxMessages {
		return nil, fmt.Errorf("hook template contains too many messages (%d): maximum is %d", n, maxMessages)
	}
	return strings.SplitN(out, "\n", maxMessages), nil
}

var ErrHookTemplateParse = errors.New("failed to parse hook template")

// commandInfo provides info about the command for which the hook was invoked.
// It is used for templated hook-messages.
type commandInfo struct {
	cmd *cobra.Command
}

// Name returns the name of the (sub)command for which the hook was invoked.
//
// It's used for backward-compatibility with old templates.
func (c commandInfo) Name() string {
	return c.command()
}

View on GitHub (pinned to 4f84911bfe)