{"record":{"id":"b6be9ac355d1796b","repo":"spacedriveapp/spacedrive","slug":"path-is-required-in-non-interactive-mode","errorCode":null,"errorMessage":"Path is required in non-interactive mode","messagePattern":"Path is required in non-interactive mode","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"apps/cli/src/domains/location/args.rs","lineNumber":44,"sourceCode":"\t/// If not provided, enters interactive mode\n\tpub path: Option<String>,\n\n\t/// Display name for the location\n\t#[arg(long)]\n\tpub name: Option<String>,\n\n\t/// Indexing mode\n\t#[arg(long, value_enum)]\n\tpub mode: Option<IndexModeArg>,\n}\n\nimpl LocationAddArgs {\n\t/// Build an SdPath from the args (non-interactive mode)\n\tpub fn build_sd_path(&self) -> anyhow::Result<SdPath> {\n\t\tlet path_str = self\n\t\t\t.path\n\t\t\t.as_ref()\n\t\t\t.ok_or_else(|| anyhow::anyhow!(\"Path is required in non-interactive mode\"))?;\n\n\t\t// Use SdPath::from_uri() to parse service-based paths or local paths\n\t\tSdPath::from_uri(path_str).map_err(|e| anyhow::anyhow!(\"Invalid path: {}\", e))\n\t}\n\n\t/// Check if interactive mode should be triggered\n\tpub fn is_interactive(&self) -> bool {\n\t\tself.path.is_none()\n\t}\n}\n\n#[derive(Args, Debug)]\npub struct LocationRemoveArgs {\n\tpub location_id: Uuid,\n\t#[arg(long, short = 'y', default_value_t = false)]\n\tpub yes: bool,\n}\n","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/spacedriveapp/spacedrive/blob/6dfeccf2113039e35f2ce735f945e70dc3e4ea45/apps/cli/src/domains/location/args.rs#L26-L62","documentation":"Thrown by LocationAddArgs::build_sd_path() when the --path argument is None. The CLI uses path absence as the signal for interactive mode (is_interactive() returns self.path.is_none()), so calling build_sd_path() without a path means a non-interactive caller asked for a path it never supplied.","triggerScenarios":"Running the non-interactive 'sd location add' code path without --path; or code calling build_sd_path() directly without first checking is_interactive(). In the CLI's own flow this fires when a script/subcommand expects a path and none was given.","commonSituations":"CI or shell scripts calling 'sd location add' while forgetting --path; typos in the flag name so clap leaves it None; reusing LocationAddArgs programmatically in tests or tools.","solutions":["Pass --path <path-or-uri> when invoking location add non-interactively","If you want the prompts, run the command without --path so the interactive flow starts","When calling build_sd_path() from code, branch on is_interactive() first"],"exampleFix":"// before\nlet sd_path = args.build_sd_path()?; // bails when path is None\n\n// after\nlet sd_path = if args.is_interactive() {\n    run_interactive_location_add(ctx).await?\n} else {\n    args.build_sd_path()?\n};","handlingStrategy":"validation","validationCode":"if !args.is_interactive() {\n    anyhow::ensure!(args.path.is_some(), \"--path is required for non-interactive location add\");\n}\nlet sd_path = args.build_sd_path()?;","typeGuard":"impl LocationAddArgs {\n    fn has_path(&self) -> bool {\n        self.path.is_some()\n    }\n}","tryCatchPattern":null,"preventionTips":["Always pass --path in scripts/CI; omit it only when you want the interactive prompts","Check is_interactive() before build_sd_path() when calling programmatically","Let clap enforce it instead: mark path as required unless a --interactive flag is set"],"tags":["cli","location","validation","arguments"],"backgroundTag":null,"analyzedSha":"6dfeccf2113039e35f2ce735f945e70dc3e4ea45","analyzedAt":"2026-08-16T11:26:17.074Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}