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
- Reduce the template output to at most 10 newline-separated messages.
- Replace iteration over large lists with a summarized single message.
- 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
- Keep hook templates to at most 10 newline-separated messages.
- Summarize multi-line output rather than dumping it.
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
- failed to parse hook template
- failed to parse hook template: flagValue: no flags found
- failed to parse hook template: arg: %dth argument not set
- unexpected hook response type
- cannot supply extra formatting options to the pretty…
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)