Problem:
Your program is using RapidJSON but when running it you see an error message like
rapidjson-example: /usr/include/rapidjson/writer.h:452: void rapidjson::Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags>::Prefix(rapidjson::Type) [with OutputStream = rapidjson::BasicOStreamWrapper<std::basic_ostream<char> >; SourceEncoding = rapidjson::UTF8<>; TargetEncoding = rapidjson::UTF8<>; StackAllocator = rapidjson::CrtAllocator; unsigned int writeFlags = 0]: Assertion `!hasRoot_' failed.
Solution:
You are using a Writer
for more than one Document
. While you can use the Stream
backing the Writer
for any number of documents, each Writer
must only be used once!
To fix the issue, create a Writer
instance (on the same output Stream
) for each document you intend to write.
Minimal code to reproduce the issue:
#include <iostream> #include <rapidjson/document.h> #include <rapidjson/writer.h> #include <rapidjson/ostreamwrapper.h> using namespace rapidjson; using namespace std; Document generateDoc() { // Generate document: {"text": "Hello JSON!"} Document doc; doc.SetObject(); // Make doc an object ! doc.AddMember("text", "Hello JSON!", doc.GetAllocator()); return doc; } int main() { // Write to stdout OStreamWrapper out(cout); Writer<OStreamWrapper> writer(out); // Write first document... generateDoc().Accept(writer); cout << "\nFirst document written!" << endl; // Write second document... generateDoc().Accept(writer); cout << "\nSecond document written!" << endl; }
That code will crash with the error message listed above:
{"text":"Hello JSON!"} First document written! rapidjson-example: /usr/include/rapidjson/writer.h:452: void rapidjson::Writer<OutputStream, SourceEncoding, TargetEncoding, StackAllocator, writeFlags>::Prefix(rapidjson::Type) [with OutputStream = rapidjson::BasicOStreamWrapper<std::basic_ostream<char> >; SourceEncoding = rapidjson::UTF8<>; TargetEncoding = rapidjson::UTF8<>; StackAllocator = rapidjson::CrtAllocator; unsigned int writeFlags = 0]: Assertion `!hasRoot_' failed. zsh: abort (core dumped) ./rapidjson-example
Here’s the fixed code that will work as intended:
#include <iostream> #include <rapidjson/document.h> #include <rapidjson/writer.h> #include <rapidjson/ostreamwrapper.h> using namespace rapidjson; using namespace std; Document generateDoc() { // Generate document: {"text": "Hello JSON!"} Document doc; doc.SetObject(); // Make doc an object ! doc.AddMember("text", "Hello JSON!", doc.GetAllocator()); return doc; } int main() { // Write to stdout OStreamWrapper out(cout); // Write first document... Writer<OStreamWrapper> writer1(out); generateDoc().Accept(writer1); cout << "\nFirst document written!" << endl; // Write second document... Writer<OStreamWrapper> writer2(out); // Same output stream as writer1! generateDoc().Accept(writer2); cout << "\nSecond document written!" << endl; }
Output:
{"text":"Hello JSON!"} First document written! {"text":"Hello JSON!"} Second document written!