remix-run/react-router · error · Error
No project directory provided
Error message
No project directory provided
What it means
projectNameStep() requires a project directory whenever the shell is non-interactive (no TTY on stdin). In non-interactive mode the CLI cannot prompt for a directory, so if no positional projectDir argument was given it aborts immediately with this error.
Solutions
- Pass the directory as a positional argument: npx create-react-router ./my-app
- In scripts, always include the project directory plus any needed flags (--yes, --no-install, --overwrite)
- If you expected the interactive prompt, run the command in a real terminal (TTY attached)
Example fix
# before (CI, non-interactive) npx create-react-router # after npx create-react-router ./my-app --yes
Defensive patterns
Strategy: validation
Validate before calling
function assertScaffoldArgs(argv: string[]): void {
const hasPositional = argv.length > 0 && !argv[0].startsWith("-");
if (!process.stdin.isTTY && !hasPositional) {
throw new Error("Non-interactive shell: pass the project directory as a positional argument");
}
}
assertScaffoldArgs(restArgs);
await createReactRouter(restArgs); Try / catch
try {
await createReactRouter(args);
} catch (e) {
if ((e as Error).message === "No project directory provided") {
console.error("Rerun with a directory: create-react-router ./my-app --yes");
process.exit(1);
}
throw e;
} Prevention
- Always pass the target directory positionally in scripts, Docker, and CI
- Assume --yes behavior whenever stdin is not a TTY
- Add a wrapper script that fails fast on missing args before invoking npx
When it happens
Trigger: Running create-react-router with no positional argument in CI, Docker, or a piped shell (stdin not a TTY); scripts redirecting stdin from /dev/null; terminal emulators that do not allocate a TTY.
Common situations: Dockerfiles, GitHub Actions steps, and smoke tests invoking the CLI without a target directory; automation where isInteractive() is false and --yes is implied.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Exiting to avoid overwriting files
- File collisions detected in a non-interactive environment
- " " is an invalid template. Run to see supported template…
- No available port found
- ️⚠️ Oops, Node v detected. react-router requires a Node…
AI-assisted analysis of remix-run/react-router@6beaca3952 (2026-08-18).
Data as JSON: /api/errors/8c9cd1c795e0f96f.
Report an issue: GitHub.
Appendix: source
Thrown at packages/create-react-router/index.ts:220
color.bold("create-react-router"),
)} ${color.bold(`v${ctx.reactRouterVersion}`)}`,
);
if (!ctx.interactive) {
log("");
info("Shell is not interactive.", [
`Using default options. This is equivalent to running with the `,
color.reset("--yes"),
` flag.`,
]);
}
}
async function projectNameStep(ctx: Context) {
// valid cwd is required if shell isn't interactive
if (!ctx.interactive && !ctx.cwd) {
error("Oh no!", "No project directory provided");
throw new Error("No project directory provided");
}
if (ctx.cwd) {
await sleep(100);
info("Directory:", [
"Using ",
color.reset(ctx.cwd),
" as project directory",
]);
}
if (!ctx.cwd) {
let { name } = await ctx.prompt({
name: "name",
type: "text",
label: title("dir"),
message: "Where should we create your new project?",
initial: "./my-react-router-app",View on GitHub (pinned to 6beaca3952)