How to fix RapidJSON Assertion `!hasRoot_' failed.

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!