This commit is contained in:
nlohmann committed 2026-10-26 21:24:35 +00:00
1 parent 41c601a7d1
commit d2e264bd84
1400 files changed
+11859 -5440

No files matched your search

+64 -30
View File
@@ -39,6 +39,8 @@ classDiagram
Exceptions are used widely within the library. They can, however, be switched off with either using the compiler flag `-fno-exceptions` or by defining the symbol [`JSON_NOEXCEPTION`](https://json.nlohmann.me/api/macros/json_noexception/index.md). In this case, exceptions are replaced by `abort()` calls. You can further control this behavior by defining `JSON_THROW_USER` (overriding `throw`), `JSON_TRY_USER` (overriding `try`), and `JSON_CATCH_USER` (overriding `catch`).
See [Working without exceptions](https://json.nlohmann.me/features/no_exceptions/index.md) for the functions that report errors without throwing.
Note that [`JSON_THROW_USER`](https://json.nlohmann.me/api/macros/json_throw_user/index.md) should leave the current scope (e.g., by throwing or aborting), as continuing after it may yield undefined behavior.
Example: switch off exceptions and log errors before aborting
@@ -73,7 +75,7 @@ Example: standard diagnostic message
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -112,7 +114,7 @@ Example: extended diagnostic message with `JSON_DIAGNOSTICS`
# define JSON_DIAGNOSTICS 1
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -161,7 +163,7 @@ The following code shows how a `parse_error` exception can be caught.
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -175,7 +177,7 @@ int main()
// output exception information
std::cout << "message: " << e.what() << '\n'
<< "exception id: " << e.id << '\n'
<< "byte position of error: " << e.byte << std::endl;
<< "byte position of error: " << e.byte << '\n';
}
}
```
@@ -247,6 +249,26 @@ Tip
- Make sure the input is correctly read. Try to write the input to standard output to check if, for instance, the input file was successfully opened.
- Paste the input to a JSON validator like <https://jsonlint.com> or a tool like [jq](https://jqlang.github.io/jq/).
Parsing a file fails at line 1, column 1 (unexpected end of input)
The messages `attempting to parse an empty input` (since version 3.11.3) and `unexpected end of input` (also the message of earlier versions for an empty input) at the very start of the input mean that the parser did not see a single character. The library only reads from the stream it is given: it does not open files and cannot tell a missing file from an empty one. The usual causes are:
- **The file was not opened.** A relative path is resolved against the *working directory of the running program*, not against the source file or the project. IDEs and build tools often start the program in a build directory (for example `build/` or `cmake-build-debug/`), so `"example.json"` may need to be `"../example.json"`. Use an absolute path to rule this out.
- **The file is empty**, or a previous run truncated it (for example when it was opened for writing).
- **The stream was already read.** A stream whose content has been consumed (by printing it with `std::cout << file.rdbuf()`, or by an earlier `accept`/`parse`/`>>`) is at its end. Parse it once, or rewind it with `seekg(0)` after clearing the state with `clear()`.
Check the stream before parsing it:
```
std::ifstream f("example.json");
if (!f.is_open())
{
std::cerr << "cannot open example.json\n";
return 1;
}
json data = json::parse(f);
```
### json.exception.parse_error.102
JSON uses the `\uxxxx` format to describe Unicode characters. Code points above 0xFFFF are split into two `\uxxxx` entries ("surrogate pairs"). This error indicates that the surrogate pair is incomplete or contains an invalid code point.
@@ -353,7 +375,7 @@ Before version 3.13.0 unreleased, a one-character array index that is not a digi
### json.exception.parse_error.110
When parsing a [binary format](https://json.nlohmann.me/features/binary_formats/index.md), the byte vector ends before the complete value has been read.
When parsing a [binary format](https://json.nlohmann.me/features/binary_formats/index.md), the byte vector ends before the complete value has been read, or (with `strict = true`) further bytes follow the value.
Example messages
@@ -371,7 +393,7 @@ Example messages
### json.exception.parse_error.112
An unexpected byte was read in a [binary format](https://json.nlohmann.me/features/binary_formats/index.md) or length information is invalid ([BSON](https://json.nlohmann.me/features/binary_formats/bson/index.md)).
An unexpected byte was read in a [binary format](https://json.nlohmann.me/features/binary_formats/index.md) or length information is invalid ([BSON](https://json.nlohmann.me/features/binary_formats/bson/index.md)). In [BON8](https://json.nlohmann.me/features/binary_formats/bon8/index.md), this exception is also thrown for a key that is not a string and for ill-formed UTF-8.
Example messages
@@ -403,9 +425,13 @@ Example messages
[json.exception.parse_error.112] parse error at byte 5: syntax error while parsing BSON document: document size 6 does not match the number of bytes read (5)
```
```
[json.exception.parse_error.112] parse error at byte 2: syntax error while parsing BON8 string: invalid UTF-8 byte: 0x80
```
### json.exception.parse_error.113
A string could not be read from a [binary format](https://json.nlohmann.me/features/binary_formats/index.md): either a value that is not a string was read where one was required (for instance as a map key), the string's length specification is invalid, or the string's bytes are not valid UTF-8 and the `error_handler` parameter of the corresponding `from_*` function is set to `strict`. By default (`error_handler_t::keep`), the bytes of a string are not checked for valid UTF-8 on read; see the ill-formed UTF-8 notes on the individual [binary format](https://json.nlohmann.me/features/binary_formats/index.md) pages for how such a string is handled depending on `error_handler`.
A string could not be read from a [binary format](https://json.nlohmann.me/features/binary_formats/index.md): either a value that is not a string was read where one was required (for instance as a map key), the string's length specification is invalid, or the string's bytes are not valid UTF-8 and the `error_handler` parameter of the corresponding `from_*` function is set to `strict`. By default (`error_handler_t::keep`), the bytes of a string are not checked for valid UTF-8 on read. This applies to the `from_*` functions that have an `error_handler` parameter; `from_bon8` does not have one. See the ill-formed UTF-8 notes on the individual [binary format](https://json.nlohmann.me/features/binary_formats/index.md) pages for how such a string is handled depending on `error_handler`. [`from_bon8()`](https://json.nlohmann.me/api/basic_json/from_bon8/index.md) never throws this exception: BON8 non-string keys and ill-formed UTF-8 are reported as [parse_error.112](#jsonexceptionparse_error112).
CBOR and MessagePack allow map keys of any type, but JSON object keys are always strings. Maps with keys of any other type (for instance integers or `null`) are therefore not supported; see the notes on [CBOR](https://json.nlohmann.me/features/binary_formats/cbor/index.md) and [MessagePack](https://json.nlohmann.me/features/binary_formats/messagepack/index.md).
@@ -447,14 +473,18 @@ Example message
### json.exception.parse_error.115
A UBJSON high-precision number could not be parsed.
A UBJSON or BJData high-precision number could not be parsed.
Example message
Example messages
```
[json.exception.parse_error.115] parse error at byte 5: syntax error while parsing UBJSON high-precision number: invalid number text: 1A
```
```
[json.exception.parse_error.115] parse error at byte 5: syntax error while parsing BJData high-precision number: invalid number text: 1A
```
### json.exception.parse_error.116
[`basic_json_document::load()`](https://json.nlohmann.me/api/basic_json_document/load/index.md) rejected an [image](https://json.nlohmann.me/features/json_view/#images): either the bytes are not one [`save()`](https://json.nlohmann.me/api/basic_json_document/save/index.md) could have written (too short, an unknown magic number or format version, or sizes that do not fit the buffer), or they are, but fail the requested [`image_check`](https://json.nlohmann.me/api/basic_json_document/load/#image_check).
@@ -483,7 +513,7 @@ The following code shows how an `invalid_iterator` exception can be caught.
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -498,7 +528,7 @@ int main()
{
// output exception information
std::cout << "message: " << e.what() << '\n'
<< "exception id: " << e.id << std::endl;
<< "exception id: " << e.id << '\n';
}
}
```
@@ -668,7 +698,7 @@ The following code shows how a `type_error` exception can be caught.
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -682,7 +712,7 @@ int main()
{
// output exception information
std::cout << "message: " << e.what() << '\n'
<< "exception id: " << e.id << std::endl;
<< "exception id: " << e.id << '\n';
}
}
```
@@ -878,7 +908,7 @@ Calling `unflatten()` on an object `{"/1", [1,2,3]}`:
The [`dump()`](https://json.nlohmann.me/api/basic_json/dump/index.md) function only works with UTF-8 encoded strings; that is, if you assign a `std::string` to a JSON value, make sure it is UTF-8 encoded. See the FAQ entry on [serializing untrusted or invalid UTF-8](https://json.nlohmann.me/home/faq/#serializing-untrusted-or-invalid-utf-8) for background and the recommended fix.
The binary writers [`to_cbor()`](https://json.nlohmann.me/api/basic_json/to_cbor/index.md), [`to_ubjson()`](https://json.nlohmann.me/api/basic_json/to_ubjson/index.md), [`to_bjdata()`](https://json.nlohmann.me/api/basic_json/to_bjdata/index.md), and [`to_bson()`](https://json.nlohmann.me/api/basic_json/to_bson/index.md) throw this exception as well for a string value or object key that is not valid UTF-8 if their `error_handler` is `strict` (the default if [`JSON_STRICT_BINARY_UTF8`](https://json.nlohmann.me/api/macros/json_strict_binary_utf8/index.md) is enabled). So does [`to_msgpack()`](https://json.nlohmann.me/api/basic_json/to_msgpack/index.md) if `error_handler_t::strict` is passed.
The binary writers [`to_cbor()`](https://json.nlohmann.me/api/basic_json/to_cbor/index.md), [`to_ubjson()`](https://json.nlohmann.me/api/basic_json/to_ubjson/index.md), [`to_bjdata()`](https://json.nlohmann.me/api/basic_json/to_bjdata/index.md), and [`to_bson()`](https://json.nlohmann.me/api/basic_json/to_bson/index.md) throw this exception as well for a string value or object key that is not valid UTF-8 if their `error_handler` is `strict` (the default if [`JSON_STRICT_BINARY_UTF8`](https://json.nlohmann.me/api/macros/json_strict_binary_utf8/index.md) is enabled). So does [`to_msgpack()`](https://json.nlohmann.me/api/basic_json/to_msgpack/index.md) if `error_handler_t::strict` is passed. [`to_bon8()`](https://json.nlohmann.me/api/basic_json/to_bon8/index.md) always throws this exception for such a string or key, regardless of [`JSON_STRICT_BINARY_UTF8`](https://json.nlohmann.me/api/macros/json_strict_binary_utf8/index.md), because the end of a BON8 string is determined from its UTF-8 encoding.
Example message
@@ -944,7 +974,7 @@ This exception was added in version 3.13.0 unreleased, together with editable [`
### json.exception.type_error.320
[`basic_json_document::save()`](https://json.nlohmann.me/api/basic_json_document/save/index.md) cannot write an [image](https://json.nlohmann.me/features/json_view/#images) of a [discarded](https://json.nlohmann.me/api/basic_json_document/is_discarded/index.md) document. [`save()`](https://json.nlohmann.me/api/basic_json_document/save/index.md) and [`load()`](https://json.nlohmann.me/api/basic_json_document/load/index.md) also throw this exception on a big-endian target, since the image format is little-endian only.
[`basic_json_document::save()`](https://json.nlohmann.me/api/basic_json_document/save/index.md) cannot write an [image](https://json.nlohmann.me/features/json_view/#images) of a [discarded](https://json.nlohmann.me/api/basic_json_document/is_discarded/index.md) document.
Example messages
@@ -952,10 +982,6 @@ Example messages
[json.exception.type_error.320] cannot save a discarded json_document
```
```
[json.exception.type_error.320] json_document images need a little-endian target
```
Note
This exception was added in version 3.13.0 unreleased, together with [images](https://json.nlohmann.me/features/json_view/#images).
@@ -986,7 +1012,7 @@ The following code shows how an `out_of_range` exception can be caught.
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
int main()
{
@@ -1000,7 +1026,7 @@ int main()
{
// output exception information
std::cout << "message: " << e.what() << '\n'
<< "exception id: " << e.id << std::endl;
<< "exception id: " << e.id << '\n';
}
}
```
@@ -1080,7 +1106,7 @@ number overflow parsing '10E1000'
An integer number cannot be represented by the binary format it is serialized to:
- [BON8](https://json.nlohmann.me/features/binary_formats/bon8/index.md) only stores integers that fit into int64, so [`to_bon8`](https://json.nlohmann.me/api/basic_json/to_bon8/index.md) throws for unsigned integers greater than 9223372036854775807.
- [BON8](https://json.nlohmann.me/features/binary_formats/bon8/index.md) only stores integers that fit into int64, so [`to_bon8`](https://json.nlohmann.me/api/basic_json/to_bon8/index.md) throws for unsigned integers greater than 9223372036854775807 and, with a number type wider than 64 bits, for any integer outside the int64 range.
- [CBOR](https://json.nlohmann.me/features/binary_formats/cbor/index.md), [MessagePack](https://json.nlohmann.me/features/binary_formats/messagepack/index.md), and [BSON](https://json.nlohmann.me/features/binary_formats/bson/index.md) store integers in at most 64 bits. With the default number types, every integer fits, but a [`number_integer_t`](https://json.nlohmann.me/api/basic_json/number_integer_t/index.md) or [`number_unsigned_t`](https://json.nlohmann.me/api/basic_json/number_unsigned_t/index.md) wider than 64 bits (e.g., `__int128`) can hold values outside the range of the format: [-2^64, 2^64-1] for CBOR, [-2^63, 2^64-1] for MessagePack, and the range of int64 (signed integers) or uint64 (unsigned integers) for BSON.
[UBJSON](https://json.nlohmann.me/features/binary_formats/ubjson/index.md) and [BJData](https://json.nlohmann.me/features/binary_formats/bjdata/index.md) never throw this exception, because they serialize integers beyond 64 bits as high-precision numbers.
@@ -1092,7 +1118,7 @@ The UBJSON and BSON writers used to throw this exception as well:
- Since version 3.9.0, integer numbers beyond int64 are serialized as high-precision UBJSON numbers.
- Since version 3.12.0, integer numbers beyond int64 are serialized as uint64 BSON numbers.
Before version 3.13.0 unreleased, CBOR, MessagePack, and BSON silently truncated integers wider than 64 bits, and BJData truncated unsigned integers wider than 64 bits.
Before version 3.13.0 unreleased, CBOR, MessagePack, and BSON silently truncated integers wider than 64 bits, and BJData truncated unsigned integers wider than 64 bits that were elements of ND-arrays with `"_ArrayType_": "uint64"`.
Example messages
@@ -1108,7 +1134,7 @@ integer number 1267650600228229401496703205376 cannot be represented by CBOR as
The size of an array or object in a [binary format](https://json.nlohmann.me/features/binary_formats/index.md) exceeds the maximal capacity: the size following `#` for [UBJSON](https://json.nlohmann.me/features/binary_formats/ubjson/index.md)/[BJData](https://json.nlohmann.me/features/binary_formats/bjdata/index.md), or the encoded length for [CBOR](https://json.nlohmann.me/features/binary_formats/cbor/index.md).
The exception is also thrown for a [UBJSON](https://json.nlohmann.me/features/binary_formats/ubjson/index.md) array of a type that is encoded by its marker alone (`Z`, `T` or `F`) whose declared count exceeds 1,048,576 (`1 << 20`). Such an array has no payload, so its count alone decides how much memory is allocated, and a handful of bytes would otherwise describe billions of values. [`to_ubjson`](https://json.nlohmann.me/api/basic_json/to_ubjson/index.md) writes longer arrays of these types without the size and type annotation, so any value it produces can still be read back.
The exception is also thrown for a [UBJSON](https://json.nlohmann.me/features/binary_formats/ubjson/index.md) array of a type that is encoded by its marker alone (`Z`, `T` or `F`) whose declared count exceeds 1,048,576 (`1 << 20`). Such an array has no payload, so its count alone decides how much memory is allocated, and a handful of bytes would otherwise describe billions of values. [`to_ubjson`](https://json.nlohmann.me/api/basic_json/to_ubjson/index.md) writes longer arrays of these types without the `$` type annotation (the `#` count and one marker per element are kept), so any value it produces can still be read back.
Example messages
@@ -1146,9 +1172,11 @@ Example message
```
enum value out of range
array index 18446744073709551616 exceeds size_type
array index 18446744073709551615 exceeds size_type
```
The second message is thrown, for instance, by `json::parse("[1, 2]").at("/18446744073709551615"_json_pointer)` on a 64-bit platform, where `size_type` is `std::size_t` and this index is `SIZE_MAX`. An index that does not fit into 64 bits (such as `18446744073709551616`) is not reported as 410 but as [`out_of_range.404`](#jsonexceptionout_of_range404).
### json.exception.out_of_range.411
A JSON Patch `add` operation cannot be applied because the target location's parent is neither an object nor an array. Per [RFC 6902](https://datatracker.ietf.org/doc/html/rfc6902), an `add` target must reference a member of an existing object or an element of an existing array; a primitive value (string, number, boolean, etc.) cannot receive a new member or element.
@@ -1163,6 +1191,8 @@ Note
This exception was added in version 3.13.0 unreleased. Before that, this situation hit an internal assertion (aborting the program in debug builds) or was silently ignored when assertions were disabled.
A `null` parent is rejected as well. Before version 3.13.0 unreleased, an `add` into a `null` parent silently converted it to an object (e.g., `add` at `/foo/bar` turned `{"foo":null}` into `{"foo":{"bar":1}}`).
### json.exception.out_of_range.412
BSON stores the length of documents, arrays, strings, and binary values in a signed 32-bit integer, and MessagePack stores the length of strings, binary values, arrays, and objects in at most an unsigned 32-bit integer. This exception is thrown when a value is too large to be described by such a length field.
@@ -1211,14 +1241,18 @@ This exception was added in version 3.13.0 unreleased. Before that, this situati
### json.exception.out_of_range.415
MessagePack's ext type and BSON's binary subtype are each stored in a single byte. This exception is thrown when serializing a [`byte_container_with_subtype`](https://json.nlohmann.me/api/byte_container_with_subtype/index.md) whose subtype exceeds 255.
MessagePack's ext type and BSON's binary subtype are each stored in a single byte. This exception is thrown when serializing a [`byte_container_with_subtype`](https://json.nlohmann.me/api/byte_container_with_subtype/index.md) whose subtype exceeds 255, the largest value the library can store in that byte.
Example message
Example messages
```
[json.exception.out_of_range.415] subtype 70000 is too large for the MessagePack ext type (max 255)
```
```
[json.exception.out_of_range.415] subtype 70000 is too large for the BSON binary subtype (max 255)
```
Note
This exception was added in version 3.13.0 unreleased. Before that, subtypes above 255 were silently truncated modulo 256 instead of raising an error.
@@ -1259,7 +1293,7 @@ The following code shows how an `other_error` exception can be caught.
#include <iostream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
using nlohmann::json;
using namespace nlohmann::literals;
int main()
@@ -1283,7 +1317,7 @@ int main()
{
// output exception information
std::cout << "message: " << e.what() << '\n'
<< "exception id: " << e.id << std::endl;
<< "exception id: " << e.id << '\n';
}
}
```
@@ -1309,7 +1343,7 @@ Executing `{"op":"test", "path":"/baz", "value":"bar"}` on `{"baz": "qux"}`:
### json.exception.other_error.502
[`to_ubjson`](https://json.nlohmann.me/api/basic_json/to_ubjson/index.md) and [`to_bjdata`](https://json.nlohmann.me/api/basic_json/to_bjdata/index.md) were called with `use_type = true` but `use_size = false`. UBJSON requires a size marker (`#`) after a type marker (`$`).
[`to_ubjson`](https://json.nlohmann.me/api/basic_json/to_ubjson/index.md) and [`to_bjdata`](https://json.nlohmann.me/api/basic_json/to_bjdata/index.md) were called with `use_type = true` but `use_size = false`, and the value contains a non-empty array or object (or, with BJData Draft 3, any binary value). UBJSON requires a size marker (`#`) after a type marker (`$`); scalars and empty arrays or objects do not throw.
Example message