{"record":{"id":"0727a15b06376212","repo":"rtk-ai/rtk","slug":"sbt-no-subcommand-specified","errorCode":null,"errorMessage":"sbt: no subcommand specified","messagePattern":"sbt: no subcommand specified","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmds/scala/sbt_cmd.rs","lineNumber":128,"sourceCode":"        RunOptions::with_tee(tee_label),\n    )\n}\n\npub fn run_test(args: &[String], verbose: u8) -> Result<i32> {\n    run_task(args, \"test\", filter_sbt_test, \"sbt_test\", verbose)\n}\n\npub fn run_compile(args: &[String], verbose: u8) -> Result<i32> {\n    run_task(args, \"compile\", filter_sbt_compile, \"sbt_compile\", verbose)\n}\n\npub fn run_run(args: &[String], verbose: u8) -> Result<i32> {\n    run_task(args, \"run\", filter_sbt_run, \"sbt_run\", verbose)\n}\n\npub fn run_other(args: &[OsString], verbose: u8) -> Result<i32> {\n    if args.is_empty() {\n        anyhow::bail!(\"sbt: no subcommand specified\");\n    }\n\n    let subcommand = args[0].to_string_lossy().into_owned();\n\n    // Integration test commands (it:test, IntegrationTest/test, etc.) produce standard\n    // ScalaTest output — filter them like `sbt test`, through the shared runner so the\n    // never_worse cap and tee hint apply (an unrecognized output would otherwise be\n    // reprinted verbatim plus the hint, i.e. more than the raw command produced).\n    if is_integration_test_cmd(&subcommand) || is_test_task(&subcommand) {\n        let mut cmd = resolved_command(\"sbt\");\n        cmd.arg(&subcommand);\n        for arg in &args[1..] {\n            cmd.arg(arg);\n        }\n\n        if verbose > 0 {\n            eprintln!(\"Running: sbt {} ...\", subcommand);\n        }","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/rtk-ai/rtk/blob/0924356b4caba4989607227b7c8824d3d8098719/src/cmds/scala/sbt_cmd.rs#L110-L146","documentation":"rtk's `sbt` proxy requires at least one argument (task or subcommand) to route output through the correct filter (test, run, it:test, etc.). Invoking `rtk sbt` with no arguments leaves nothing to dispatch, so run_other bails with this message.","triggerScenarios":"Running `rtk sbt` with no task, or calling scala/sbt_cmd::run_other(&[], verbose) with an empty argument vector.","commonSituations":"CI scripts parameterized like `rtk sbt $TASK` where $TASK is empty; users who expect bare `rtk sbt` to drop into the sbt interactive shell; a Makefile target that lost its TASK argument.","solutions":["Pass an sbt task explicitly: `rtk sbt test`, `rtk sbt run`, `rtk sbt it:test`.","Fix the invoking script/CI variable so the task name is actually set (guard `[ -n \"$TASK\" ]`).","Use `rtk proxy sbt` to run sbt's interactive shell or any unfiltered invocation.","Run `sbt` directly if you want its own REPL/usage behavior."],"exampleFix":"// before\nrtk sbt $TASK    # TASK empty -> sbt: no subcommand specified\n// after\nrtk sbt \"${TASK:-test}\"   # or fail fast: : \"${TASK:?TASK must be set}\"","handlingStrategy":"validation","validationCode":"if [ -z \"$TASK\" ]; then echo \"usage: rtk sbt <task> [args]\" >&2; exit 2; fi\nrtk sbt \"$TASK\" \"$@\"","typeGuard":"fn has_args(args: &[OsString]) -> bool { !args.is_empty() }","tryCatchPattern":"match rtk_result {\n    Err(e) if e.to_string().contains(\"sbt: no subcommand\") => {\n        eprintln!(\"supply an sbt task, e.g. rtk sbt test\");\n        std::process::exit(2);\n    }\n    other => other?,\n}","preventionTips":["Always pass an sbt task explicitly in scripts and CI matrices.","Fail fast on empty task variables with ${TASK:?TASK not set}.","Use `rtk proxy sbt` for the interactive shell or unfiltered runs."],"tags":["cli","scala","sbt","missing-argument"],"backgroundTag":"missing-cli-argument","analyzedSha":"0924356b4caba4989607227b7c8824d3d8098719","analyzedAt":"2026-09-19T19:25:29.612Z","contentChangedAt":"2026-09-19T19:25:29.612Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}