{"record":{"id":"8c9cd1c795e0f96f","repo":"remix-run/react-router","slug":"no-project-directory-provided","errorCode":null,"errorMessage":"No project directory provided","messagePattern":"No project directory provided","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/create-react-router/index.ts","lineNumber":220,"sourceCode":"      color.bold(\"create-react-router\"),\n    )} ${color.bold(`v${ctx.reactRouterVersion}`)}`,\n  );\n\n  if (!ctx.interactive) {\n    log(\"\");\n    info(\"Shell is not interactive.\", [\n      `Using default options. This is equivalent to running with the `,\n      color.reset(\"--yes\"),\n      ` flag.`,\n    ]);\n  }\n}\n\nasync function projectNameStep(ctx: Context) {\n  // valid cwd is required if shell isn't interactive\n  if (!ctx.interactive && !ctx.cwd) {\n    error(\"Oh no!\", \"No project directory provided\");\n    throw new Error(\"No project directory provided\");\n  }\n\n  if (ctx.cwd) {\n    await sleep(100);\n    info(\"Directory:\", [\n      \"Using \",\n      color.reset(ctx.cwd),\n      \" as project directory\",\n    ]);\n  }\n\n  if (!ctx.cwd) {\n    let { name } = await ctx.prompt({\n      name: \"name\",\n      type: \"text\",\n      label: title(\"dir\"),\n      message: \"Where should we create your new project?\",\n      initial: \"./my-react-router-app\",","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/remix-run/react-router/blob/1fd704a7dabcbe3ae09d7387b460e6acaba30ec1/packages/create-react-router/index.ts#L202-L238","documentation":"Thrown in projectNameStep() when the shell is not interactive (no TTY) and no project directory positional argument was given (ctx.cwd is undefined). In non-interactive mode the CLI cannot prompt for a directory, so it requires one to be supplied on the command line. The check is `if (!ctx.interactive && !ctx.cwd)`.","triggerScenarios":"Running create-react-router with no positional arg in CI, a Dockerfile, a shell script without a TTY, or any piped/non-TTY stdin. Also when stdin/stdout are redirected so isInteractive() returns false.","commonSituations":"CI script that runs npx create-react-router expecting to prompt; Docker RUN without a TTY; piping yes into the command; running under a process supervisor that doesn't allocate a TTY.","solutions":["Provide the project directory as a positional argument: create-react-router ./my-app.","Add --yes (or -y) and a positional directory for fully non-interactive runs: create-react-router ./my-app --yes.","If you expected a TTY, run the command in an interactive terminal (not via ssh -T or piped stdin).","In CI/Docker, allocate a pseudo-TTY (docker run -it) only if you want prompts; otherwise supply args."],"exampleFix":"// before -- fails in CI\nnpx create-react-router\n// after -- explicit project directory\nnpx create-react-router ./my-app --yes","handlingStrategy":"validation","validationCode":"// Detect non-interactive shell before invoking the CLI\nimport { statSync } from 'node:fs';\nfunction isInteractiveStdin(): boolean {\n  try { return statSync(0).isCharacterDevice(); } catch { return false; }\n}\n// In your wrapper:\nconst projectDir = process.argv[2];\nif (!isInteractiveStdin() && !projectDir) {\n  throw new Error('Pass a project directory: create-react-router <dir>');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass a positional project directory in CI/ scripted invocations.","Pair non-interactive runs with --yes to suppress all prompts.","Allocate a TTY (docker run -it, ssh without -T) when you actually want prompts.","Validate argv before calling createReactRouter programmatically."],"tags":["cli","interactive","non-interactive","create-react-router"],"backgroundTag":null,"analyzedSha":"1fd704a7dabcbe3ae09d7387b460e6acaba30ec1","analyzedAt":"2026-08-12T13:54:57.804Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}