This error tells you that ArduinoJson tried to instantiate a class but couldn’t find a constructor without arguments.

How did we get there?

This error typically happens when extracting a non-default-constructible type from a JsonDocument.

For example, if you have a class like this:

class Complex {
  double _real, _imag;
 public:
  // (no default constructor)
  explicit Complex(double r, double i) : _real(r), _imag(i) {}
  double real() const { return _real; }
  double imag() const { return _imag; }
};

If you try to extract a Complex from a JsonDocument like this:

Complex sensor = doc["value"];

You will get the following error:

In file included from .../ArduinoJson.hpp:42:0,
                 from .../ArduinoJson.h:9,
                 from MyProject.ino:9:
.../ArduinoJson/Variant/ConverterImpl.hpp: In instantiation of 'static T ArduinoJson::V721JB11::Converter<T, Enable>::fromJson(ArduinoJson::V721JB11::JsonVariantConst) [with T = Complex; Enable = void]':
.../ArduinoJson/Variant/VariantRefBaseImpl.hpp:23:32:   required from 'T ArduinoJson::V721JB11::detail::VariantRefBase<TDerived>::as() const [with T = Complex; TDerived = ArduinoJson::V721JB11::detail::MemberProxy<ArduinoJson::V721JB11::JsonDocument&, const char*>]'
.../ArduinoJson/Variant/VariantRefBase.hpp:53:17:   required from 'ArduinoJson::V721JB11::detail::VariantRefBase<TDerived>::operator T() const [with T = Complex; <template-parameter-2-2> = void; TDerived = ArduinoJson::V721JB11::detail::MemberProxy<ArduinoJson::V721JB11::JsonDocument&, const char*>]'
MyProject.ino:46:31:   required from here
.../ArduinoJson/Variant/ConverterImpl.hpp:39:7: error: no matching function for call to 'Complex::Complex()'
     T result; // Error here? See https://arduinojson.org/v7/non-default-constructible/
       ^~~~~~
MyProject.ino:14:12: note: candidate: Complex::Complex(double, double)
   explicit Complex(double r, double i) : _real(r), _imag(i) {}
            ^~~~~~~
MyProject.ino:14:12: note:   candidate expects 2 arguments, 0 provided
MyProject.ino:11:7: note: candidate: constexpr Complex::Complex(const Complex&)
 class Complex {
       ^~~~~~~
MyProject.ino:11:7: note:   candidate expects 1 argument, 0 provided
MyProject.ino:11:7: note: candidate: constexpr Complex::Complex(Complex&&)
MyProject.ino:11:7: note:   candidate expects 1 argument, 0 provided
In file included from .../ArduinoJson.hpp:42:0,
                 from .../ArduinoJson.h:9,
                 from MyProject.ino:9:
.../ArduinoJson/Variant/ConverterImpl.hpp:40:20: error: invalid initialization of reference of type 'String&' from expression of type 'Complex'
     convertFromJson(src, result);  // Error here? See https://arduinojson.org/v7/unsupported-as/
     ~~~~~~~~~~~~~~~^~~~~~~~~~~~~
.../ArduinoJson/Variant/ConverterImpl.hpp:278:13: note: in passing argument 2 of 'void ArduinoJson::V721JB11::convertFromJson(ArduinoJson::V721JB11::JsonVariantConst, String&)'
 inline void convertFromJson(JsonVariantConst src, ::String& dst) {
             ^~~~~~~~~~~~~~~

How to fix this error?

ArduinoJson supports user-defined types through “custom converters”. You can define converters in two forms:

  1. Function-based converters, which are the easiest to write but only work for default-constructible types.
  2. Class-based converters, which are more complex to write but work for any type.

In our example, the type is not default-constructible, so we need to use a class-based converter, such as the following:

namespace ArduinoJson {
template <>
struct Converter<Complex> {
  static void toJson(const Complex& src, JsonVariant dst) {
    dst["real"] = src.real();
    dst["imag"] = src.imag();
  }

  static Complex fromJson(JsonVariantConst src) {
    return Complex(src["real"], src["imag"]);
  }

  static bool checkJson(JsonVariantConst src) {
    return src["real"].is<double>() && src["imag"].is<double>();
  }
};
}

The converter class is a specialization of ArduinoJson::Converter<T>, where T is the type you want to support. This specialization must provide the three static methods shown above and be defined in the ArduinoJson namespace.

See also

Global warming stripes by Professor Ed Hawkins (University of Reading)