slimtoolkit/slim · error
only one escape parser directive can be used
Error message
only one escape parser directive can be used
What it means
This error is raised by possibleParserDirective (called from processLine) when a Dockerfile contains more than one '# escape = <char>' parser directive. Parser directives must appear at the top of the file, before any instruction or comment, and may not be repeated.
Source
Thrown at pkg/docker/dockerfile/ast/parser.go:166
d.escapeToken = rune(s[0])
d.lineContinuationRegex = regexp.MustCompile(`\` + s + `[ \t]*$`)
return nil
}
// possibleParserDirective looks for parser directives, eg '# escapeToken=<char>'.
// Parser directives must precede any builder instruction or other comments,
// and cannot be repeated.
func (d *Directive) possibleParserDirective(line string) error {
if d.processingComplete {
return nil
}
tecMatch := tokenEscapeCommand.FindStringSubmatch(strings.ToLower(line))
if len(tecMatch) != 0 {
for i, n := range tokenEscapeCommand.SubexpNames() {
if n == "escapechar" {
if d.escapeSeen {
return errors.New("only one escape parser directive can be used")
}
d.escapeSeen = true
return d.setEscapeToken(tecMatch[i])
}
}
}
d.processingComplete = true
return nil
}
// NewDefaultDirective returns a new Directive with the default escapeToken token
func NewDefaultDirective() *Directive {
directive := Directive{}
directive.setEscapeToken(string(DefaultEscapeToken))
return &directive
}
View on GitHub (pinned to 81940d17fa)
Solutions
- Keep only one '# escape=' directive, at the very top of the Dockerfile
- Remove the duplicate directive from merged/generated fragments
- If different escaping is needed mid-file, restructure the Dockerfile instead of re-declaring the directive
Example fix
# before # escape=` # escape=` FROM alpine # after # escape=` FROM alpine
Defensive patterns
Strategy: validation
Validate before calling
// Go: ensure at most one escape parser directive in the Dockerfile text
func countEscapeDirectives(src string) int {
count, re := 0, regexp.MustCompile(`(?im)^#[ \t]*escape[ \t]*=`)
for range re.FindAllString(src, -1) { count++ }
return count
}
if countEscapeDirectives(dockerfile) > 1 {
return fmt.Errorf("duplicate # escape directive")
} Prevention
- Declare '# escape=' at most once, at the very top of the Dockerfile
- Strip per-fragment directives when merging generated Dockerfiles
- Place the directive before any instruction or other comment so it is recognized at all
When it happens
Trigger: Writing two '# escape=\' lines in the same Dockerfile (both before the first instruction); concatenating/merging Dockerfiles (e.g., in generated or templated files) that each included their own escape directive.
Common situations: Merging base Dockerfiles with FROM-scratch templates; code generators emitting the directive per-fragment; hand-edits duplicating the header block.
Related errors
- when using JSON array syntax, arrays must be comprised of st
- unknown instruction
- invalid Dockerfile
- invalid ESCAPE '%s'. Must be ` or \
- malformed HEALTHCHECK instruction: %q
AI-assisted analysis of slimtoolkit/slim@81940d17fa (2026-08-31).
Data as JSON: /api/errors/1fe1a27bcf09ff92.
Report an issue: GitHub.