build silently excludes any file path containing 'test' substring (Compiler.backendIgnoreFiles)
#15341 opened on May 8, 2026
Description
Summary
medusa build silently excludes any file whose path contains the substring test. The intent is clearly to skip directories like integration-tests/, test/, unit-tests/, but the implementation uses a naive String.includes() against the full path, so user-authored fixture/seed scripts with test in the filename (e.g. seed-test-accounts.ts, reset-test-vendor-password.ts) are dropped from the build with no warning.
Observed on @medusajs/framework@2.12.5 and @medusajs/medusa@2.12.5. Code path appears unchanged at the time of writing on latest (2.14.2).
Reproduction
-
In a Medusa app, add a script at
src/scripts/reset-test-vendor-password.ts:```ts import type { ExecArgs } from "@medusajs/framework/types" export default async function ({ container }: ExecArgs) { console.log("hello") } ```
-
Run `npx medusa build`.
-
Inspect `.medusa/server/src/scripts/` — `reset-test-vendor-password.js` is missing.
-
Rename to `reset-fixture-vendor-password.ts`, rebuild — file now appears.
-
Same outcome for `seed-test-x.ts`, `my-test-helper.ts`, etc.
Code citation
`@medusajs/framework/dist/build-tools/compiler.js`:
L54-59 — hardcoded ignore list: ```js __classPrivateFieldSet(this, _Compiler_backendIgnoreFiles, [ "integration-tests", "test", "unit-tests", "src/admin", ], "f"); ```
L398-402 — naive substring match against full path: ```js async function _Compiler_emitBuildOutput(tsConfig, chunksToIgnore, dist) { const ts = await ...; const filesToCompile = tsConfig.fileNames.filter((fileName) => { return !chunksToIgnore.some((chunk) => fileName.includes(`${chunk}`)); }); ```
Expected behavior
Skip files inside directories named `integration-tests/`, `test/`, `unit-tests/`, or `src/admin/` (matching path segments). Files named `test.ts` outside those directories should build normally.
Actual behavior
Any path containing the substring `test` anywhere — including in a filename — is filtered out. Affected our project today: 3 separate fixture/seed scripts had been tracked in the repo for weeks but never appeared in deployed builds.
Suggested fix
Match path segments rather than substrings. A few options:
- `fileName.includes(path.sep + chunk + path.sep)` — matches `/test/` directories but not `seed-test-x.ts`. Edge case: chunk at start/end of relative path needs separate handling.
- Compute segments via `path.relative(rootDir, fileName).split(path.sep)` and check `.includes(chunk)` against the array.
- Push the exclusion into `tsconfig.exclude` (proper glob semantics) instead of post-hoc filtering.
Impact
- Silent: no warning, no log. Files just don't appear in `.medusa/server/`.
- Non-obvious: user has to read `@medusajs/framework/dist/build-tools/compiler.js` to discover the cause.
- Real-world: 3 fixture/seed scripts in our app, including one that had been in the repo for ~2 months across 700+ commits without anyone noticing it never reached production.
Workaround
Rename any `test.ts` files to drop the `test` substring (we used `fixture.ts`).