{"record":{"id":"9d7926ccf36bf710","repo":"clockworklabs/SpacetimeDB","slug":"project-name-is-required-in-non-interactive-mode","errorCode":null,"errorMessage":"PROJECT_NAME is required in non-interactive mode","messagePattern":"PROJECT_NAME is required in non-interactive mode","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/cli/src/subcommands/init.rs","lineNumber":271,"sourceCode":"        println!(\"{}\", \"Continuing with local deployment.\".yellow());\n        Ok(false)\n    }\n}\n\nfn slugify(name: &str) -> String {\n    name.to_case(Case::Kebab)\n}\n\nasync fn get_project_name(options: &InitOptions, is_interactive: bool) -> anyhow::Result<String> {\n    if let Some(name) = &options.project_name {\n        if is_interactive {\n            println!(\"{} {}\", \"Project name:\".bold(), name);\n        }\n        return Ok(name.clone());\n    }\n\n    if !is_interactive {\n        anyhow::bail!(\"PROJECT_NAME is required in non-interactive mode\");\n    }\n\n    let default_project_name = options\n        .project_name_default\n        .clone()\n        .unwrap_or_else(|| \"my-spacetime-app\".to_string());\n\n    let theme = ColorfulTheme::default();\n    let name = Input::with_theme(&theme)\n        .with_prompt(\"Project name\")\n        .default(default_project_name)\n        .validate_with(|input: &String| -> Result<(), String> {\n            if input.trim().is_empty() {\n                return Err(\"Project name cannot be empty\".to_string());\n            }\n            Ok(())\n        })\n        .interact_text()?","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/clockworklabs/SpacetimeDB/blob/524b4487d949b61a07d4f39c862d1290259dfd20/crates/cli/src/subcommands/init.rs#L253-L289","documentation":"init prompts for a project name interactively (defaulting to my-spacetime-app), but with `--non-interactive` (or any scripted context that disables prompting) there is no prompt, so the name must already be provided via `--project-name` or init aborts before doing anything.","triggerScenarios":"`spacetime init --non-interactive --lang rust` with no `--project-name`; CI jobs, Dockerfiles, and make targets that call init without a name; piping stdin so the interactive prompt cannot appear.","commonSituations":"CI pipelines and container builds; automation scripts written against interactive behavior; forgetting that the flag disabling prompts also removes the name default.","solutions":["Pass the name: `spacetime init --non-interactive --project-name my-app --lang rust`","Or run interactively (omit --non-interactive and keep a TTY) to get the prompt with its default","In containers, use `docker run -it` / `script -qc` if you actually want prompts"],"exampleFix":"# before\nspacetime init --non-interactive --lang rust\n\n# after\nspacetime init --non-interactive --project-name my-app --lang rust","handlingStrategy":"validation","validationCode":"# Require a name whenever prompts are disabled:\nif [[ \"$NON_INTERACTIVE\" == \"true\" && -z \"$PROJECT_NAME\" ]]; then\n  echo \"--project-name is required with --non-interactive\" >&2; exit 2\nfi\nspacetime init --non-interactive --project-name \"$PROJECT_NAME\" --lang rust","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat --non-interactive as a contract: supply --project-name, --lang or --template up front","In CI, fail fast on missing variables before invoking the CLI so errors stay actionable"],"tags":["init","non-interactive","project-name","ci"],"backgroundTag":"missing-required-argument","analyzedSha":"524b4487d949b61a07d4f39c862d1290259dfd20","analyzedAt":"2026-08-16T23:58:54.611Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}