vercel/turborepo · error · Error

Invalid example name

Error message

Invalid example name: ${name}

What it means

downloadAndExtractExample validates the example name against /^[a-zA-Z0-9_-]+$/ before using it in a git sparse-checkout path. Names with slashes, dots, spaces, or any non [A-Za-z0-9_-] character are rejected. This prevents path traversal (../) and git argument injection when the name is interpolated into clone paths.

Solutions

  1. Use the bare directory name of the example, e.g. 'with-react-native-web' not 'examples/with-react-native-web'
  2. For a full custom repo/path, pass the GitHub URL form instead of a nested example path
  3. If creating your own template tree, keep example directory names alphanumeric with - and _ only
  4. List valid names from the examples directory or the create-turbo prompts

Example fix

# before
pnpm create turbo@latest --example examples/with-vite
# Error: Invalid example name: examples/with-vite

# after
pnpm create turbo@latest --example with-vite
Defensive patterns

Strategy: validation

Validate before calling

const EXAMPLE_NAME_RE = /^[a-zA-Z0-9_-]+$/;

function isValidExampleName(name: string): boolean {
  return EXAMPLE_NAME_RE.test(name);
}
// if (!isValidExampleName(name)) suggest examples from the registry instead;

Type guard

function isExampleName(name: string): name is string {
  return /^[a-zA-Z0-9_-]+$/.test(name);
}

Prevention

When it happens

Trigger: Passing an example name like 'examples/basic-app', 'apps/web..', '../evil', 'basic app', or an empty string to downloadAndExtractExample (or create-turbo --example with a nested path instead of a bare directory name under examples/).

Common situations: Users copying a path from the turborepo repo (examples/my-app) instead of the bare name (my-app), passing a URL where a name is expected, or scripts that forward un sanitized argv into the example parameter.

Related errors


AI-assisted analysis of vercel/turborepo@f9245100cf (2026-08-17). Data as JSON: /api/errors/86d8c4e25a3bbeb2. Report an issue: GitHub.

Appendix: source

Thrown at packages/turbo-utils/src/examples.ts:540

  try {
    rmSync(tempDir, {
      recursive: true,
      force: true,
      maxRetries: 5,
      retryDelay: 100
    });
  } catch (error) {
    warn(
      `Unable to remove temporary directory ${tempDir}:\n${formatError(error)}`
    );
  }
}

export async function downloadAndExtractExample(root: string, name: string) {
  // Validate example name to prevent path traversal and argument injection
  // Only allow alphanumeric characters, hyphens, and underscores
  if (!name || !/^[a-zA-Z0-9_-]+$/.test(name)) {
    throw new Error(`Invalid example name: ${name}`);
  }

  // Normalize and validate the root directory to prevent unsafe git arguments
  const normalizedRoot = resolve(root);
  assertSafeGitArgument(normalizedRoot, "project root");

  const tempDir = join(normalizedRoot, ".turbo-clone-temp");
  assertSafeGitArgument(tempDir, "temporary directory");

  try {
    // Clone with partial clone (no blobs) and no checkout
    runGit([
      "clone",
      "--filter=blob:none",
      "--no-checkout",
      "--depth",
      "1",
      "--sparse",

View on GitHub (pinned to f9245100cf)