---
title: "Report errors with line and column"
url: https://recursiveai.org/oneyaml/rust/cookbook/errors-with-line-and-column/
description: "Get the Y#### code, line, column and path of a YAML error in Rust, print a rustc-style snippet, and collect every error in a file at once."
version: "1.2.0"
---

# Report errors with line and column

Validate a YAML file and say exactly what’s wrong and where. Every oneyaml error has a stable `Y####` code, a position and, for typed reads, the path to the value.

```rust
use oneyaml::{ColumnUnit, Document, LineIndex};
use serde::Deserialize;

#[derive(Debug, Deserialize)]
struct Config {
    #[allow(dead_code)]
    port: u16,
}

fn main() {
    // A typed read: the error has a code, a position and a path.
    let src = "port: 99999\n";
    let err = oneyaml::from_str::<Config>(src).unwrap_err();
    let at = err.location().expect("a position");
    println!("{} at line {}, column {}", err.code(), at.line(), at.column());
    println!("path: {}", err.path().map(|p| p.to_string()).unwrap_or_default());
    println!("one line: {err}");

    // Or the rustc-style snippet, for a terminal.
    print!("{}", err.render(src));

    // Every error in a file, not only the first.
    let src = "name: web\nname: api\nports: [80, 443\n";
    let parsed = Document::parse_recovering(src);
    let lines = LineIndex::new(src);
    for d in parsed.diagnostics() {
        let at = lines.line_col(d.primary.span.start, ColumnUnit::Char).expect("in bounds");
        println!("{}:{}: {} {}", at.line + 1, at.column + 1, d.code, d.message);
    }
}
```

```text
Y3001 at line 1, column 7
path: port
one line: integer 99999 is out of range for u16 at port (1:7)
error[Y3001]: integer 99999 is out of range for u16
 --> 1:7
  |
1 | port: 99999
  |       ^^^^^
  |
  = path: port
2:1: Y1013 duplicate key `name`
4:1: Y0022 flow collection is not closed
```

## Good to know

- `err.location()` gives a 1-based line and column (in characters) and the byte offset. `err.span()` gives the byte range.
- **Codes are stable.** Match on `err.code()` (or `err.kind()` for the broad category), not on the message. Codes are never reused.
- **Fixes come with many errors.** `err.diagnostic().suggestions` holds suggested fixes you can apply with `fix.apply(src)`. A fix is marked machine-applicable only when it can’t change what the rest of the file means.
- `Document::parse_recovering` keeps going past the first error and returns the document with every diagnostic. `render_diagnostics` prints them all as snippets.
- With the `miette` feature, `Error` implements `miette::Diagnostic`, for miette’s reports.

More in [diagnostics](https://recursiveai.org/oneyaml/rust/docs/guide/#diagnostics).
