# Fix the string extraction agent scanning node_modules i18n folders

## TL;DR

The agent wastes hours scanning dependency folders, so exclude node_modules and other vendored paths from the scan roots. Extraction should only read your source trees, never installed packages. Set explicit include roots and exclude patterns, then the scan finishes in seconds and the catalog has no third-party strings.

## The error

```text
Extraction agent scanned 40,000 files including node_modules/.bin locales
run took 25 minutes, catalog full of third-party strings
```

## Fix it

### Step 1: Check what the agent actually scanned

```bash
grep -n "node_modules" logs/extract-run.log | head -5
```

Expected: You see dependency paths in the scan.

### Step 2: Set explicit scan roots to your source folders

```bash
node -e "console.log('config: include [\"src\", \"app\"], exclude [\"**/node_modules/**\", \"**/dist/**\", \"**/.git/**\"]')"
```

Expected: The config names source roots and excludes vendored paths.

### Step 3: Re-run extraction and time it

```bash
time node scripts/extract-strings.js | tail -3
```

Expected: The run finishes fast with no dependency files scanned.

### Step 4: Diff the catalog against the previous one

```bash
node -e "console.log('third-party strings should be gone, your string count should drop to just your own')"
```

Expected: The catalog contains only your strings.

## When to use this

- String extraction scans node_modules or vendored folders
- Extraction is slow and the catalog has third-party strings

## When NOT to use this

- You intentionally extract from a vendored package, allowlist that one path
- Extraction is slow on your own huge monorepo, that is a sharding problem

## Tool and version compatibility

- Any extraction agent or script with configurable scan roots
- Glob exclude patterns

## Variant phrasings

### agent also scans the .git folder

Same fix. Exclude .git, it has no strings you want and it is huge.

### monorepo with packages/*/node_modules

Exclude **/node_modules/** recursively, one pattern covers all nesting levels.

## Why it happens

Default glob patterns like **/*.js match everything under the working directory, including installed dependencies. Dependency folders dwarf your source tree, so the scan spends nearly all its time there and picks up strings you never wrote.

## Edge cases

- Symlinked packages can reintroduce node_modules, exclude by real path too
- Generated folders like dist and build deserve the same exclusion
- Keep an allowlist escape hatch for the rare vendored package you own

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_WU1oRB71VVTwPVPwUn9SHw
