sinelaw/fresh · error
Too many '+ ' arguments (at most one is allowed)
Error message
Too many '+<line>' arguments (at most one is allowed)
What it means
Validation guard in apply_plus_line_args that rejects command lines supplying more than one '+<line>' argument (e.g. `editor +5 +10 file.rs`). The editor accepts at most one start-line position; multiple ones are ambiguous, so the whole argument list is rejected before any file is opened rather than silently using the last or first value.
Solutions
- Pass only one '+<line>' argument for the whole invocation
- Use explicit file:line syntax for each file instead, e.g. `fresh file1.txt:10 file2.txt:20`
- Fix wrapper scripts/aliases that inject a '+<line>' argument automatically
- Keep the jump target in the file argument: `fresh +50 file.txt` == `fresh file.txt:50`
Example fix
// before fresh +10 +20 notes.txt // after fresh notes.txt:10 # or per-file explicit locations: fresh a.txt:10 b.txt:20
Defensive patterns
Strategy: validation
Validate before calling
let plus_args: Vec<_> = std::env::args().skip(1).filter(|a| a.starts_with('+') && a[1..].chars().all(|c| c.is_ascii_digit())).collect();
if plus_args.len() > 1 { eprintln!("pass at most one +<line>"); } 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 error: {e}"),
Ok(()) => {},
} Prevention
- Use file:line syntax for multiple per-file locations
- Audit shell aliases/wrappers for auto-injected +line arguments
- Remember +<line> is a single, whole-invocation jump target
When it happens
Trigger: Invoking the editor like `fresh +10 +20 file.txt` — more than one argument beginning with '+' is counted and rejected.
Common situations: Script aliases that already add a '+line' argument while the user adds another; copy-pasting multiple jump targets; misunderstanding the shorthand as repeatable per-file.
Understand the failure class
Background: "Unknown argument", "Invalid value", and "must be one of": invalid CLI argument errors explained — this error's family across 35 libraries.
Related errors
- '+ ' requires a file argument (e.g. 'fresh + file.txt'…
- 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/4085de842280b9ad.
Report an issue: GitHub.
Appendix: source
Thrown at crates/fresh-editor/src/main.rs:1093
/// uses).
fn apply_plus_line_args(files: Vec<String>) -> AnyhowResult<Vec<String>> {
let mut line: Option<usize> = None;
let mut plus_count = 0usize;
let mut rest: Vec<String> = Vec::with_capacity(files.len());
for f in files {
match parse_plus_line_arg(&f) {
Some(n) => {
plus_count += 1;
line = Some(n);
}
None => rest.push(f),
}
}
let Some(line) = line else {
return Ok(rest);
};
if plus_count > 1 {
anyhow::bail!("Too many '+<line>' arguments (at most one is allowed)");
}
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)
}View on GitHub (pinned to 67894ca546)