{"record":{"id":"7a9ce4f5a1c0a720","repo":"sinelaw/fresh","slug":"line-requires-a-file-argument-e-g-fresh-line-file-txt-which","errorCode":null,"errorMessage":"'+{line}' requires a file argument (e.g. 'fresh +{line} file.txt', which is equivalent to 'fresh file.txt:{line}')","messagePattern":"'\\+(.+?)' requires a file argument \\(e\\.g\\. 'fresh \\+(.+?) file\\.txt', which is equivalent to 'fresh file\\.txt:(.+?)'\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fresh-editor/src/main.rs","lineNumber":1112,"sourceCode":"    }\n    match rest.iter_mut().find(|f| f.as_str() != \"-\") {\n        Some(target) => {\n            // Only annotate a file that carries no explicit location\n            // yet — `fresh +50 file.txt:10` keeps the explicit 10.\n            // Remote specs (`user@host:path`, `ssh://…`) take the\n            // same `:line` suffix, so they work too.  A malformed\n            // `ssh://` target is left alone; it errors downstream.\n            let has_line = match parse_location(target) {\n                Ok(ParsedLocation::Local(fl)) => fl.line.is_some(),\n                Ok(ParsedLocation::Remote(rl)) => rl.line.is_some(),\n                Err(_) => true,\n            };\n            if !has_line {\n                target.push_str(&format!(\":{}\", line));\n            }\n            Ok(rest)\n        }\n        None => anyhow::bail!(\n            \"'+{line}' requires a file argument (e.g. 'fresh +{line} file.txt', \\\n             which is equivalent to 'fresh file.txt:{line}')\"\n        ),\n    }\n}\n\nfn parse_file_location(input: &str) -> FileLocation {\n    use std::path::{Component, Path};\n\n    let empty = FileLocation {\n        path: PathBuf::from(input),\n        line: None,\n        column: None,\n        end_line: None,\n        end_column: None,\n        message: None,\n    };\n","sourceCodeStart":1094,"sourceCodeEnd":1130,"githubUrl":"https://github.com/sinelaw/fresh/blob/67894ca5463dbd7a89bb31add4627c27d6b79d83/crates/fresh-editor/src/main.rs#L1094-L1130","documentation":"A '+<line>' argument was given but no file argument followed, so there is nothing to attach the line number to. The parser bails with guidance showing the equivalent file:line form. (The DECLARED-AS/USED-AT metadata in the report refers to unrelated symbols; the error itself lives in the shown main.rs region.)","triggerScenarios":"Invoking `fresh +50` with no file arguments (or only '-' stdin placeholders) so the match on rest.iter_mut().find(...) yields None.","commonSituations":"Typing the line jump before remembering the filename; scripting where the filename variable is empty; piping stdin while expecting '+line' to apply to the piped buffer.","solutions":["Add the target file after the '+<line>' argument: `fresh +50 file.txt`","Use the equivalent explicit form `fresh file.txt:50`","If reading from stdin ('-'), drop the '+<line>' argument as it cannot apply","Fix scripts so an empty filename variable does not produce a bare '+line' invocation"],"exampleFix":"// before\nfresh +50\n// after\nfresh +50 file.txt\n# equivalent:\nfresh file.txt:50","handlingStrategy":"validation","validationCode":"let args: Vec<String> = std::env::args().skip(1).collect();\nif args.iter().any(|a| is_plus_line_arg(a)) && args.iter().filter(|a| a.as_str() != \"-\").count() < 2 {\n    eprintln!(\"'+<line>' needs a file argument\");\n}","typeGuard":"fn is_plus_line_arg(a: &str) -> bool {\n    a.len() > 1 && a.starts_with('+') && a[1..].chars().all(|c| c.is_ascii_digit())\n}","tryCatchPattern":"match editor::launch(args) {\n    Err(e) => { eprintln!(\"usage: fresh +<line> <file>  (or fresh <file>:<line>)\"); std::process::exit(2); }\n    Ok(()) => {},\n}","preventionTips":["Always follow +<line> with a filename","Prefer the equivalent file:line form to avoid argument-order pitfalls","Guard scripts against empty filename variables producing bare +line args","Do not combine +<line> with '-' stdin mode"],"tags":["cli","arguments"],"backgroundTag":"missing-required-argument","analyzedSha":"67894ca5463dbd7a89bb31add4627c27d6b79d83","analyzedAt":"2026-09-13T15:04:03.701Z","contentChangedAt":"2026-09-13T15:04:03.701Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}