Skip to content

Negation extglob produces different results depending on order of alternatives #154

@saschabratton

Description

@saschabratton

The order of alternatives inside a negation extglob !(...) affects matching results. Reordering the alternatives produces different (incorrect) results even though the order should not matter.

const picomatch = require('picomatch');
const opts = { dot: true };

// "amplify" first — incorrectly matches
const isMatch1 = picomatch('!(amplify/**|data/**|deploy/**)**', opts);
console.log(isMatch1('amplify/backend/function/jest.config.ts')); // true (WRONG)

// "amplify" last — correctly does not match
const isMatch2 = picomatch('!(deploy/**|data/**|amplify/**)**', opts);
console.log(isMatch2('amplify/backend/function/jest.config.ts')); // false (correct)

Expected behavior

Both patterns should produce identical results regardless of the order of alternatives inside !(...). The file amplify/backend/function/jest.config.ts should not match either pattern since it falls under amplify/**.

Actual behavior

When amplify/** is the first alternative, amplify/backend/function/jest.config.ts incorrectly matches. When amplify/** is moved to the last position, it correctly does not match.

Environment

  • picomatch: 2.3.1
  • node: v25.2.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions