# How to Catch and Handle yaml-cpp Parsing Exceptions: A Complete Guide

> Learn to catch and handle yaml-cpp parsing exceptions using standard C++ try-catch blocks. Understand malformed YAML errors with location metadata for robust error handling.

- Repository: [Jesse Beder/yaml-cpp](https://github.com/jbeder/yaml-cpp)
- Tags: how-to-guide
- Published: 2026-07-11

---

**yaml-cpp throws `YAML::ParserException` (derived from `YAML::Exception`) when encountering malformed YAML, providing location metadata via the `mark` member that you can catch using standard C++ try-catch blocks.**

The `jbeder/yaml-cpp` library converts YAML streams into events or nodes through the `YAML::Parser` class. When the parser encounters invalid syntax, duplicate anchors, or malformed tags, it raises specific exceptions that carry precise line and column information. Understanding this exception hierarchy allows you to distinguish between parsing errors and representation errors while extracting detailed diagnostic data.

## The yaml-cpp Exception Hierarchy

All yaml-cpp exceptions derive from `YAML::Exception`, which itself inherits from `std::runtime_error`. This hierarchy is defined in [[`include/yaml-cpp/exceptions.h`](https://github.com/jbeder/yaml-cpp/blob/main/include/yaml-cpp/exceptions.h)](https://github.com/jbeder/yaml-cpp/blob/master/include/yaml-cpp/exceptions.h).

The inheritance chain looks like this:

```

YAML::Exception                ← std::runtime_error
 └─ YAML::ParserException      ← YAML::Exception
 └─ YAML::RepresentationException ← YAML::Exception
      ├─ InvalidScalar
      ├─ KeyNotFound / TypedKeyNotFound
      ├─ BadConversion / TypedBadConversion
      ├─ BadDereference
      ├─ BadSubscript
      ├─ BadPushback
      ├─ BadInsert
      └─ NonUniqueMapKey

```

**`YAML::ParserException`** is thrown during the tokenization and event generation phase. **Representation exceptions** (like `BadConversion` or `KeyNotFound`) occur later when you access or manipulate the resulting `YAML::Node` objects.

## Where Parsing Exceptions Originate

The primary throw point is `Parser::HandleNextDocument`, declared in [[`include/yaml-cpp/parser.h`](https://github.com/jbeder/yaml-cpp/blob/main/include/yaml-cpp/parser.h)](https://github.com/jbeder/yaml-cpp/blob/master/include/yaml-cpp/parser.h) (lines 55-58). When you call `YAML::Load` or use the streaming operator `>>`, the library internally invokes this method, which may throw if the input violates the YAML specification.

The concrete exception construction happens in [[`src/singleparser.cpp`](https://github.com/jbeder/yaml-cpp/blob/main/src/singleparser.cpp)](https://github.com/jbeder/yaml-cpp/blob/master/src/singleparser.cpp), where the tokenizer detects invalid tokens. Representation errors are generated in [[`src/node/node.cpp`](https://github.com/jbeder/yaml-cpp/blob/main/src/node/node.cpp)](https://github.com/jbeder/yaml-cpp/blob/master/src/node/node.cpp) when node access operations fail.

## Catching yaml-cpp Exceptions in Practice

You can catch exceptions using either the high-level `YAML::Load` API or the low-level `Parser` interface. Both approaches throw the same exception types.

### High-Level API with YAML::Load

The `YAML::Load` function internally constructs a `Parser` and processes the stream. Wrap this call to catch syntax errors:

```cpp
#include <fstream>
#include <iostream>
#include <yaml-cpp/yaml.h>

int main() {
    std::ifstream fin("config.yaml");
    if (!fin) {
        std::cerr << "Could not open config.yaml\n";
        return 1;
    }

    try {
        // Parser invoked implicitly by the Load function
        YAML::Node cfg = YAML::Load(fin);
        std::cout << "Version: " << cfg["version"].as<std::string>() << '\n';
    }
    catch (const YAML::ParserException& ex) {
        // Specific handling for syntax errors
        std::cerr << "Parsing error: " << ex.what() << '\n';
        std::cerr << "  at line " << ex.mark.line + 1
                  << ", column " << ex.mark.column + 1 << '\n';
        return 1;
    }
    catch (const YAML::Exception& ex) {
        // Catches all other yaml-cpp errors (representation, conversion, etc.)
        std::cerr << "YAML error: " << ex.what() << '\n';
        return 1;
    }
    catch (const std::exception& ex) {
        // Fallback for standard library exceptions
        std::cerr << "Unexpected error: " << ex.what() << '\n';
        return 1;
    }

    return 0;
}

```

### Low-Level Parser API

For event-driven parsing, instantiate `YAML::Parser` directly and call `HandleNextDocument`:

```cpp
#include <fstream>
#include <yaml-cpp/parser.h>
#include <yaml-cpp/eventhandler.h>

int main() {
    std::ifstream fin("data.yaml");
    YAML::Parser parser(fin);
    YAML::NodeBuilder builder;  // implements EventHandler
    
    try {
        while (parser.HandleNextDocument(builder)) {
            YAML::Node doc = builder.GetRootNode();
            // Process document...
        }
    }
    catch (const YAML::ParserException& e) {
        std::cerr << "Parse failure: " << e.what() << '\n';
        std::cerr << "Location: line " << e.mark.line + 1 << '\n';
    }
}

```

## Accessing Error Location and Messages

Every `YAML::Exception` contains a **`YAML::Mark`** object recording the exact error position. According to the implementation in [`exceptions.h`](https://github.com/jbeder/yaml-cpp/blob/main/exceptions.h), the exception message is constructed by `Exception::build_what` and includes the line and column.

To extract diagnostic information:

- **`e.what()`**: Returns the complete error message including filename (if available), line, column, and description.
- **`e.mark.line`**: Zero-indexed line number where the error occurred.
- **`e.mark.column`**: Zero-indexed column number.

Since indices are zero-based, add 1 when displaying to users for readability.

## Summary

- **yaml-cpp** throws **`YAML::ParserException`** during tokenization and **`YAML::RepresentationException`** during node access.
- The exception hierarchy is rooted in **`YAML::Exception`** (defined in [`include/yaml-cpp/exceptions.h`](https://github.com/jbeder/yaml-cpp/blob/main/include/yaml-cpp/exceptions.h)), allowing you to catch all yaml-cpp errors with a single handler or specialize for specific failure types.
- **Location data** is available via the `mark` member, providing `line` and `column` integers.
- **Primary throw point** is `Parser::HandleNextDocument` in [`include/yaml-cpp/parser.h`](https://github.com/jbeder/yaml-cpp/blob/main/include/yaml-cpp/parser.h), invoked by both high-level `YAML::Load` and manual parsing loops.

## Frequently Asked Questions

### What is the base class for all yaml-cpp exceptions?

**`YAML::Exception`** is the abstract base class for all yaml-cpp errors, inheriting from `std::runtime_error`. It is defined in [`include/yaml-cpp/exceptions.h`](https://github.com/jbeder/yaml-cpp/blob/main/include/yaml-cpp/exceptions.h). Catching this base class will handle `ParserException`, `RepresentationException`, and all their derivatives like `BadConversion` or `KeyNotFound`.

### How do I get the line number where a YAML parsing error occurred?

Access the **`mark`** member of the caught exception. This `YAML::Mark` struct contains `line` and `column` members (zero-indexed). For example: `ex.mark.line + 1` gives the human-readable line number. This data is populated by the parser in [`src/singleparser.cpp`](https://github.com/jbeder/yaml-cpp/blob/main/src/singleparser.cpp) and propagated through the exception hierarchy.

### Should I catch YAML::ParserException or YAML::Exception?

**Catch `YAML::ParserException`** if you only need to handle syntax errors (malformed YAML, invalid tags, duplicate anchors). **Catch `YAML::Exception`** if you want to handle all yaml-cpp failures including type conversion errors (`BadConversion`) and missing keys (`KeyNotFound`). For complete safety, catch `YAML::Exception` first, then `std::exception`.

### Why does yaml-cpp use exceptions instead of error codes?

The library uses C++ exceptions to separate error handling from normal control flow, consistent with the C++ standard library approach. The `Parser` class throws `ParserException` immediately upon detecting invalid tokens in [`src/singleparser.cpp`](https://github.com/jbeder/yaml-cpp/blob/main/src/singleparser.cpp), preventing invalid state propagation. This design allows you to use RAII for resource cleanup while centralizing error handling in catch blocks.