dagger/dagger · error
illegal exclusion pattern: "!"
Error message
illegal exclusion pattern: "!"
What it means
After trimming and filepath.Clean, a pattern consisting solely of '!' would be an exclusion of nothing — meaningless and likely a typo. NewPattern detects this case and returns a dedicated error instead of constructing a Pattern that excludes nothing.
Source
Thrown at util/patternmatcher/patternmatcher.go:290
cleanedPattern string
dirs []string
regexp *regexp.Regexp
exclusion bool
}
var ErrEmptyPattern = errors.New("empty pattern")
func NewPattern(p string) (*Pattern, error) {
// Eliminate leading and trailing whitespace.
p = strings.TrimSpace(p)
if p == "" {
return nil, ErrEmptyPattern
}
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:]
}
// 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))
return newp, nil
}View on GitHub (pinned to 82ba2681db)
Solutions
- Remove the bare '!' line from the pattern list or ignore file
- If you meant to exclude something, put a path after the '!', e.g. '!keep.txt'
- Check template/variable expansion so the exclusion path isn't interpolated to empty
- Filter out or validate patterns of length 1 before passing them to the matcher
Example fix
// before (.dockerignore) ! // after !Dockerfile
Defensive patterns
Strategy: validation
Validate before calling
func validExclusion(p string) bool {
p = strings.TrimSpace(p)
return !(p == "!" || strings.TrimSpace(strings.TrimPrefix(p, "!")) == "")
} Type guard
func isBareExclusion(p string) bool { return strings.TrimSpace(p) == "!" } Try / catch
p, err := NewPattern(raw)
if err != nil && strings.Contains(err.Error(), "illegal exclusion pattern") {
// skip or report the malformed '!' line
} Prevention
- Never emit a '!' without a path after it in ignore files
- Validate template-expanded patterns so exclusions never interpolate to empty
- Test ignore-file parsing in CI to catch bare '!' lines
When it happens
Trigger: Calling NewPattern("!"), NewPattern(" ! "), or passing "!" as one of the patterns to New or Glob.
Common situations: A .dockerignore line containing just '!'; a script or template that interpolated an empty value after the '!' prefix (e.g. '!${EXCLUDE}') leaving a bare '!'; a user misunderstanding exclusion syntax.
Related errors
- empty pattern
- close generated overlay path %q: %w
- open generated overlay path %q: %w
- inspect %q: %w
- failed to read go.mod: %w
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/7ae36b302cf45b40.
Report an issue: GitHub.