nushell/nushell · info
invalid xml document
Error message
invalid xml document
What it means
The 'invalid xml document' expect in query xml: the code first checks `if let Err(err) = package` and returns a labeled 'Invalid XML document' error for any parse failure, then calls package.expect("invalid xml document") on the value that just passed that check. The expect is therefore dead/unreachable — by the time it runs, the Result is guaranteed Ok. Users never see this panic; malformed XML input produces the proper labeled error with the parser message instead.
Source
Thrown at crates/nu_plugin_query/src/query_xml.rs:139
return Err(
LabeledError::new("problem with input data").with_label("query missing", call.head)
);
}
};
let node_output_options = NodeOutputOptions::from_call(call);
let xpath = build_xpath(query_string, span)?;
let input_string = input.coerce_str()?;
let package = parser::parse(&input_string);
if let Err(err) = package {
return Err(
LabeledError::new("Invalid XML document").with_label(err.to_string(), input.span())
);
}
let package = package.expect("invalid xml document");
let document = package.as_document();
let mut context = Context::new();
let mut namespaces = namespaces.unwrap_or_default();
if namespaces.get("xml").is_none() {
// XML namespace is always present, so we add it explicitly
// it's used in attributes like `xml:lang`, `xml:base`, etc.
namespaces.insert(
"xml",
Value::string("http://www.w3.org/XML/1998/namespace", call.head),
);
}
// NB: `xmlns:whatever=` or `xmlns=` may look like an attribute, but XPath doesn't treat it as such.
// Those are namespaces, and they are available through a separate axis (`namespace::`)
// Thus we don't need to register a namespace for `xmlns` prefixView on GitHub (pinned to 8e03210652)
Solutions
- No fix needed for users; malformed XML already yields a labeled 'Invalid XML document' error
- Maintainer cleanup: bind the success value in the check (`let package = parser::parse(&input_string).map_err(...)?.as_document()` style) to remove the unreachable expect
- Keep the error return before the unwrap when refactoring
Example fix
// before
let package = parser::parse(&input_string);
if let Err(err) = package {
return Err(LabeledError::new("Invalid XML document").with_label(err.to_string(), input.span()));
}
let package = package.expect("invalid xml document");
// after: no unreachable expect
let package = parser::parse(&input_string).map_err(|err| {
LabeledError::new("Invalid XML document").with_label(err.to_string(), input.span())
})?; Defensive patterns
Strategy: try-catch
Validate before calling
// users cannot reach this panic; to fail gracefully on bad input the command already:
// 1) parses the XML, 2) returns LabeledError "Invalid XML document" on failure.
// You can pre-validate before invoking:
let looks_like_xml = input_str.trim_start().starts_with('<'); Type guard
fn is_parseable_xml(s: &str) -> bool {
roxmltree::Document::parse(s).is_ok() // independent pre-check
} Try / catch
// in plugin command run(): the error is already a labeled error, so just bubble it up
match execute_xpath(...) {
Ok(v) => Ok(v),
Err(e) => Err(e), // LabeledError carries "Invalid XML document" + parser detail
} Prevention
- Feed well-formed XML to 'query xml' (balanced tags, single root, correct declaration)
- Strip leading whitespace/BOM before parsing pasted XML
- For maintainers: bind the Ok value via map_err + ? so no expect remains
When it happens
Trigger: None for the panic itself: any malformed XML input (unbalanced tags, bad encoding, wrong root structure) exits at the earlier `if let Err` block with LabeledError 'Invalid XML document'. The expect could only fire if the early-return check were removed or reordered.
Common situations: Running 'query xml' with a --query XPath against non-XML input — you get the graceful labeled error, not this panic. Relevant only to maintainers refactoring query_xml.rs who might break the check-then-expect ordering.
Related errors
- must be OK
- Failed to create cursor
- we guarantee that 1 entry is always in a list
- always ok
- Failed to create cursor
AI-assisted analysis of nushell/nushell@8e03210652 (2026-08-17).
Data as JSON: /api/errors/048365114a467894.
Report an issue: GitHub.