slimtoolkit/slim · error
illegal exclusion pattern: "!"
Error message
illegal exclusion pattern: "!"
What it means
This error is raised by newPatternMatcher in the dockerignore matcher when a pattern line is a bare '!' with nothing after it. An exclusion pattern must exclude something; '!' alone is meaningless and rejected. It is surfaced through Match when the pattern list is compiled.
Source
Thrown at pkg/docker/dockerignore/dockerignore.go:148
patterns []*pattern
exclusions bool
}
func newPatternMatcher(patterns []string) (*patternMatcher, error) {
pm := &patternMatcher{
patterns: make([]*pattern, 0, len(patterns)),
}
for _, p := range patterns {
// Eliminate leading and trailing whitespace.
p = strings.TrimSpace(p)
if p == "" {
continue
}
p = filepath.Clean(p)
newp := &pattern{}
if p[0] == '!' {
if len(p) == 1 {
return nil, errors.New("illegal exclusion pattern: \"!\"")
}
newp.exclusion = true
p = p[1:]
pm.exclusions = true
}
// Do some syntax checking on the pattern.
// filepath's Match() has some really weird rules that are inconsistent
// so instead of trying to dup their logic, just call Match() for its
// error state and if there is an error in the pattern return it.
// If this becomes an issue we can remove this since its really only
// needed in the error (syntax) case - which isn't really critical.
if _, err := filepath.Match(p, "."); err != nil {
return nil, err
}
newp.cleanedPattern = p
newp.dirs = strings.Split(p, string(os.PathSeparator))
pm.patterns = append(pm.patterns, newp)
}View on GitHub (pinned to 81940d17fa)
Solutions
- Edit the .dockerignore (or pattern list) and remove the standalone '!' line.
- If a negation was intended, append the path after it, e.g. '!node_modules/important.txt'.
- Add a pre-parse check that skips or rejects lines where p == "!" after trimming.
- Lint .dockerignore files in CI to catch malformed negation patterns.
Example fix
// before (.dockerignore) node_modules ! // after node_modules !node_modules/.keep
Defensive patterns
Strategy: validation
Validate before calling
cleaned := strings.TrimSpace(line)
if cleaned == "!" {
return fmt.Errorf("bare '!' exclusion in pattern list line %d", i)
} Try / catch
patterns, err := dockerignore.Parse(parsedLines)
// or catch at Match time:
if err != nil {
if strings.Contains(err.Error(), "illegal exclusion pattern") {
// point user to the offending .dockerignore line
}
return err
} Prevention
- Lint .dockerignore in CI; reject lines that are exactly '!'.
- When generating exclusions programmatically, only emit '!' followed by a non-empty pattern.
- Trim whitespace and skip empty lines before matching.
- Document negation syntax for users editing ignore files.
When it happens
Trigger: Calling dockerignore Match (which builds a patternMatcher via newPatternMatcher) with a pattern list containing a line that is exactly "!".
Common situations: A hand-edited .dockerignore with a stray '!' on its own line; a script generating exclusion rules with a missing pattern after the negation prefix; template rendering that left an empty exclusion.
Related errors
AI-assisted analysis of slimtoolkit/slim@81940d17fa (2026-08-31).
Data as JSON: /api/errors/df31aac4b1eff5a5.
Report an issue: GitHub.