oven-sh/bun · error · Error

Vendor ' ' does not have a test directory

Error message

Vendor '${name}' does not have a test directory: ${testParentPath}

What it means

Thrown during vendor test setup: after cloning and checking out the vendor repo at its pinned tag, the runner sanity-checks that the checkout contains the files it needs to run tests. This variant fires when the vendor's test parent directory is absent, meaning the pinned tag either moved its tests or ships without them, so the runner cannot discover any test files to execute.

Solutions

  1. Fix the testPath entries in test/vendor.json to match the repo layout
  2. Update the tag if the test directory moved
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at scripts/runner.node.mjs:2433 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16). Data as JSON: /api/errors/dd57979414e88d80. Report an issue: GitHub.

Appendix: source

Thrown at scripts/runner.node.mjs:2433

        if (!ok) throw new Error(`failed to fetch tag ${tag} for vendor '${name}': ${error}`);

        ({ ok, error } = await spawnSafe({
          command: "git",
          args: ["checkout", tag],
          timeout: testTimeout,
          cwd: vendorPath,
        }));
        if (!ok) throw new Error(`failed to checkout tag ${tag} for vendor '${name}': ${error}`);

        const packageJsonPath = join(vendorPath, "package.json");
        if (!existsSync(packageJsonPath)) {
          throw new Error(`Vendor '${name}' does not have a package.json: ${packageJsonPath}`);
        }

        const testPathPrefix = testPath || "test";
        const testParentPath = join(vendorPath, testPathPrefix);
        if (!existsSync(testParentPath)) {
          throw new Error(`Vendor '${name}' does not have a test directory: ${testParentPath}`);
        }

        const isTest = path => {
          if (!isJavaScriptTest(path)) {
            return false;
          }

          if (typeof skipTests === "boolean") {
            return !skipTests;
          }

          if (typeof skipTests === "object") {
            for (const [glob, reason] of Object.entries(skipTests)) {
              const pattern = new RegExp(`^${glob.replace(/\*/g, ".*")}$`);
              if (pattern.test(path) && reason) {
                return false;
              }
            }

View on GitHub (pinned to 8c5296ac45)