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

  1. Keep only one '# escape=' directive, at the very top of the Dockerfile
  2. Remove the duplicate directive from merged/generated fragments
  3. 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

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


AI-assisted analysis of slimtoolkit/slim@81940d17fa (2026-08-31). Data as JSON: /api/errors/1fe1a27bcf09ff92. Report an issue: GitHub.