warpdotdev/warp · error
Failed to parse Grep output, unexpected format
Error message
Failed to parse Grep output, unexpected format
What it means
The grep output parser expects every line to contain at least 'file:line-number' as the first two colon-separated fields. A line where either the file or line-number slot is missing - blank lines, 'Binary file x matches', banners, or grep diagnostics without that shape - fails the whole parse with this error.
Source
Thrown at app/src/ai/blocklist/action_model/execute/grep.rs:656
/// Parses the output of grep or a grep-like command into the format that we pass
/// back to the agent.
///
/// Assumes the output is in the format:
/// `{relative_file_path}:{line_number}:{line_contents}`.
fn parse_grep_output(
output: &str,
shell_launch_data: Option<ShellLaunchData>,
current_working_directory: Option<String>,
) -> anyhow::Result<Vec<GrepFileMatch>> {
let mut matched_files = HashMap::new();
for line in output.trim().split("\n") {
let mut parts = line.split(":");
let file = parts.next();
let line_number = parts.next();
let (Some(file), Some(line_number)) = (file, line_number) else {
return Err(anyhow::anyhow!(
"Failed to parse Grep output, unexpected format"
));
};
let line_number = match line_number.parse::<usize>() {
Ok(line_number) => line_number,
Err(e) => {
return Err(anyhow::anyhow!(
"Failed to parse line number in Grep output: {:?}",
e
));
}
};
matched_files
.entry(file)
.or_insert_with(Vec::new)
.push(GrepLineMatch { line_number });
}View on GitHub (pinned to e72fd7aacb)
Solutions
- Invoke grep with flags that pin the format: -n, --no-messages (-s), and -I to skip binaries
- Strip blank lines and known banner lines before parsing
- Make the parser skip-and-warn on malformed lines instead of failing the entire result
- Pin the grep implementation used across platforms
Example fix
// before
for line in output.trim().split("\n") {
let mut parts = line.split(":");
let (Some(file), Some(line_number)) = (parts.next(), parts.next()) else {
return Err(anyhow::anyhow!("Failed to parse Grep output, unexpected format"));
};
}
// after
for line in output.trim().split("\n") {
let mut parts = line.split(":");
let (Some(file), Some(line_number)) = (parts.next(), parts.next()) else {
log::warn!("Skipping malformed grep line: {line:?}");
continue;
};
} Defensive patterns
Strategy: fallback
Validate before calling
let parseable = output.lines().all(|l| {
let mut p = l.split(':');
matches!((p.next(), p.next()), (Some(f), Some(n)) if !f.is_empty() && n.parse::<usize>().is_ok())
});
if !parseable { sanitize_output_before_parsing(output); } Type guard
fn is_grep_match_line(line: &str) -> bool {
let mut p = line.split(':');
matches!((p.next(), p.next()), (Some(f), Some(n))
if !f.is_empty() && !f.starts_with("grep") && n.parse::<usize>().is_ok())
} Try / catch
match parse_grep_output(&output, shell, cwd).await {
Err(e) if e.to_string().contains("unexpected format") => {
let clean: String = output.lines().filter(|l| is_grep_match_line(l)).collect::<Vec<_>>().join("\n");
parse_grep_output(&clean, shell, cwd).await // retry on filtered output
}
r => r,
} Prevention
- Always run grep with -n, --no-messages, and -I so output is strictly file:line:content
- Trim output and drop blank/binary-file/banner lines before parsing
- Prefer skipping malformed lines with a warning over failing the whole search result
When it happens
Trigger: Output passed to the parser contains a line whose split(':') yields fewer than two parts: blank trailing lines, 'Binary file ... matches' entries, command banners, or truncated output (grep.rs:649-658).
Common situations: Grep invoked without flags that guarantee the file:line format (missing -n, no --no-messages); binary files matched; stderr or headers mixed into stdout; output from a different grep implementation (BSD/GNU/BusyBox) with different formatting.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to parse line number in Grep output: {:?}
- invalid value 'integration'
- invalid value 'schedule'
- invalid value 'secret'
- invalid value 'harness-support'
AI-assisted analysis of warpdotdev/warp@e72fd7aacb (2026-08-16).
Data as JSON: /api/errors/6eb0a846819ae981.
Report an issue: GitHub.