microsoft/edit · error
A language ID is required when reading from stdin
Error message
A language ID is required when reading from stdin
What it means
run_render resolves which highlighting entrypoint to use. When rendering stdin there is no file path to glob-match against entrypoint path patterns, so a language ID is mandatory; if the --language option is absent the function bails immediately.
Source
Thrown at crates/lsh-bin/src/main.rs:131
) -> anyhow::Result<()> {
let assembly = generator.assemble()?;
let entrypoint = if let Some(language) = language {
assembly.entrypoints.iter().find(|ep| ep.name.replace('_', "-") == language).ok_or_else(
|| anyhow::anyhow!("No highlighting definition found for language {language:?}"),
)?
} else if let Some(path) = path {
assembly
.entrypoints
.iter()
.find(|ep| {
ep.paths.iter().any(|pattern| {
glob_match(pattern.as_bytes(), path.as_os_str().as_encoded_bytes())
})
})
.ok_or_else(|| anyhow::anyhow!("No matching highlighting definition found"))?
} else {
bail!("A language ID is required when reading from stdin");
};
let mut color_map = Vec::new();
let mut unknown_kinds = Vec::new();
for hk in &assembly.highlight_kinds {
let color = match hk.identifier {
"other" => "",
"comment" => "\x1b[32m", // Green
"method" => "\x1b[93m", // Bright Yellow
"string" => "\x1b[91m", // Bright Red
"variable" => "\x1b[96m", // Bright Cyan
"constant.language" => "\x1b[94m", // Bright Blue
"constant.numeric" => "\x1b[92m", // Bright Green
"keyword.control" => "\x1b[95m", // Bright Magenta
"keyword.other" => "\x1b[94m", // Bright Blue
"keyword.preprocessor" => "\x1b[94m", // Bright BlueView on GitHub (pinned to 826b4c097b)
Solutions
- Pass the language ID when reading from stdin, e.g. `lsh --language rust` (dashes in entrypoint names map to underscores).
- Alternatively render an actual file path so run_render can glob-match the path against entrypoint patterns.
- In wrapper scripts, derive the language from the file extension before switching to stdin mode.
Example fix
// before cat main.rs | lsh // after cat main.rs | lsh --language rust
Defensive patterns
Strategy: validation
Validate before calling
let lang = language_arg.ok_or("--language is required when piping to stdin")?;
if input_is_stdin && lang.is_none() {
eprintln!("usage: cat file | lsh --language rust");
std::process::exit(2);
} Prevention
- Make --language mandatory in any wrapper that feeds lsh via stdin.
- Derive the language ID from the original file extension before switching to stdin.
- Prefer passing a real file path so lsh can auto-detect via glob patterns.
When it happens
Trigger: Piping content to lsh via stdin without specifying a language ID, i.e. language is None and path is also None when run_render is called from run.
Common situations: Running `cat file.rs | lsh` instead of `cat file.rs | lsh --language rust`; editors/CI integrations invoking lsh on stdin without wiring through the language flag from their config.
Understand the failure class
Background: "--flag is required" and "must specify" CLI errors: how missing-required-flag validation works and how to fix it — this error's family across 20 libraries.
Related errors
- At least one .lsh file or directory is required
- No highlighting definition found for language {language:?}
- No matching highlighting definition found
- invalid language: "{}"
- unrecognized arguments: {:?}
AI-assisted analysis of microsoft/edit@826b4c097b (2026-09-06).
Data as JSON: /api/errors/46554774524ba2dc.
Report an issue: GitHub.