{"record":{"id":"da88a30e14ad8866","repo":"nikivdev/code","slug":"pass-either-a-subcommand-or-a-bare-import-path-no","errorCode":null,"errorMessage":"pass either a subcommand or a bare import path, not both","messagePattern":"pass either a subcommand or a bare import path, not both","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/ext.rs","lineNumber":22,"sourceCode":"use std::process::Command;\n\nuse crate::cli::{ExtAction, ExtCommand};\nuse crate::code;\nuse crate::config;\nuse crate::flow_config;\nuse crate::setup::add_gitignore_entry;\nuse anyhow::{Context, Result, bail};\n\npub fn run(cmd: ExtCommand) -> Result<()> {\n    match (cmd.action, cmd.path) {\n        (Some(ExtAction::List { json }), None) => list_extensions(json),\n        (Some(ExtAction::Doctor { json }), None) => doctor_extensions(json),\n        (Some(ExtAction::Enable { name }), None) => enable_extension(&name),\n        (Some(ExtAction::Disable { name }), None) => disable_extension(&name),\n        (Some(ExtAction::Init { name, force }), None) => init_extension(&name, force),\n        (Some(ExtAction::Import { path }), None) => import_external_path(&path),\n        (None, Some(path)) => import_external_path(&path),\n        (Some(_), Some(_)) => bail!(\"pass either a subcommand or a bare import path, not both\"),\n        (None, None) => list_extensions(false),\n    }\n}\n\nfn list_extensions(as_json: bool) -> Result<()> {\n    let extensions = flow_config::discover_extensions()?;\n    if as_json {\n        println!(\"{}\", serde_json::to_string_pretty(&extensions)?);\n        return Ok(());\n    }\n\n    if extensions.is_empty() {\n        println!(\n            \"No Flow extensions discovered. Create one with `f ext init <name>` under {}\",\n            flow_config::flow_root_dir().join(\"extensions\").display()\n        );\n        return Ok(());\n    }","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/ext.rs#L4-L40","documentation":"The `f ext` dispatcher supports two mutually exclusive invocation styles: a subcommand (list/doctor/enable/disable/init/import) or a bare import path argument. Passing both in one command is ambiguous, so `run` bails immediately with this usage error before executing anything.","triggerScenarios":"`f ext <subcommand> <path>` — the parser matched both an ExtAction (e.g. Import { path }) and a bare path positional, hitting the (Some(_), Some(_)) arm at src/ext.rs:22.","commonSituations":"Habit from other CLIs where subcommand plus positional is normal; copying an example that used the bare-path form but prepending a subcommand anyway; shell completion or wrapper script injecting an extra argument.","solutions":["Use one form only: `f ext import <path>` OR `f ext <path>` — not both","Drop the subcommand if you intended the shortcut: `f ext ./my-extension`","Drop the bare path if you intended the subcommand: `f ext import ./my-extension`","Check any wrapper script/alias that might append an extra positional argument"],"exampleFix":"// before\nf ext import ./my-ext ./my-ext   # subcommand AND bare path\n// after\nf ext import ./my-ext            # or: f ext ./my-ext","handlingStrategy":"validation","validationCode":"// validate CLI args before dispatching to `f ext`\nlet args: Vec<String> = std::env::args().skip(1).collect();\nlet subcommands = [\"list\", \"doctor\", \"enable\", \"disable\", \"init\", \"import\"];\nlet has_sub = args.first().map_or(false, |a| subcommands.contains(&a.as_str()));\nlet has_bare_path = args.len() > 1 && !subcommands.contains(&args[1].as_str());\nif has_sub && has_bare_path {\n    bail!(\"pass either a subcommand or a bare import path, not both\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pick one invocation form: subcommand OR bare path, never both","Check wrapper scripts/aliases don't append extra positionals","Consult `f ext --help` for accepted forms","Update old scripts that predate the bare-path shortcut"],"tags":["cli","usage","argument-parsing"],"backgroundTag":"cli-usage-error","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}