sinelaw/fresh · error
'+ ' requires a file argument (e.g. 'fresh + file.txt'…
Error message
'+{line}' requires a file argument (e.g. 'fresh +{line} file.txt', which is equivalent to 'fresh file.txt:{line}') What it means
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.)
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
Example fix
// before fresh +50 // after fresh +50 file.txt # equivalent: fresh file.txt:50
Defensive patterns
Strategy: validation
Validate before calling
let args: Vec<String> = std::env::args().skip(1).collect();
if args.iter().any(|a| is_plus_line_arg(a)) && args.iter().filter(|a| a.as_str() != "-").count() < 2 {
eprintln!("'+<line>' needs a file argument");
} Type guard
fn is_plus_line_arg(a: &str) -> bool {
a.len() > 1 && a.starts_with('+') && a[1..].chars().all(|c| c.is_ascii_digit())
} Try / catch
match editor::launch(args) {
Err(e) => { eprintln!("usage: fresh +<line> <file> (or fresh <file>:<line>)"); std::process::exit(2); }
Ok(()) => {},
} Prevention
- 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
When it happens
Trigger: Invoking `fresh +50` with no file arguments (or only '-' stdin placeholders) so the match on rest.iter_mut().find(...) yields None.
Common situations: 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.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Too many '+ ' arguments (at most one is allowed)
- Cannot mix local and remote files. Use either local paths…
- Cannot open files from multiple remote hosts. First
- No data piped to stdin
- Cannot mix local and remote files. Use either local paths…
AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13).
Data as JSON: /api/errors/7a9ce4f5a1c0a720.
Report an issue: GitHub.
Appendix: source
Thrown at crates/fresh-editor/src/main.rs:1112
}
match rest.iter_mut().find(|f| f.as_str() != "-") {
Some(target) => {
// Only annotate a file that carries no explicit location
// yet — `fresh +50 file.txt:10` keeps the explicit 10.
// Remote specs (`user@host:path`, `ssh://…`) take the
// same `:line` suffix, so they work too. A malformed
// `ssh://` target is left alone; it errors downstream.
let has_line = match parse_location(target) {
Ok(ParsedLocation::Local(fl)) => fl.line.is_some(),
Ok(ParsedLocation::Remote(rl)) => rl.line.is_some(),
Err(_) => true,
};
if !has_line {
target.push_str(&format!(":{}", line));
}
Ok(rest)
}
None => anyhow::bail!(
"'+{line}' requires a file argument (e.g. 'fresh +{line} file.txt', \
which is equivalent to 'fresh file.txt:{line}')"
),
}
}
fn parse_file_location(input: &str) -> FileLocation {
use std::path::{Component, Path};
let empty = FileLocation {
path: PathBuf::from(input),
line: None,
column: None,
end_line: None,
end_column: None,
message: None,
};
View on GitHub (pinned to 67894ca546)