How do we get this error?

This error occurs when you try to call JsonVariant::is<T>() with a type T that ArduinoJson doesn’t support (neither natively nor through a custom converter).

For example, imagine you have the following structure:

struct Point {
  int x, y;
};

Suppose your program contains a line like this:

if (doc["point"].is<Point>()) 
  // ...

The compiler will produce an error along those lines:

In file included from .../ArduinoJson.hpp:42,
                 from .../ArduinoJson.h:9,
                 from MyProject.ino:1:
.../ArduinoJson/Variant/ConverterImpl.hpp: In instantiation of 'static bool ArduinoJson::V701PB2::Converter<T, Enable>::checkJson(ArduinoJson::V701PB2::JsonVariantConst) [with T = Point; Enable = void]':
.../ArduinoJson/Variant/VariantRefBase.hpp:99:35:   required from 'typename ArduinoJson::V701PB2::detail::enable_if<(((! ArduinoJson::V701PB2::detail::ConverterNeedsWriteableRef<T>::value) && (! ArduinoJson::V701PB2::detail::is_same<T, char*>::value)) && (! ArduinoJson::V701PB2::detail::is_same<T, char>::value)), bool>::type ArduinoJson::V701PB2::detail::VariantRefBase<TDerived>::is() const [with T = Point; TDerived = ArduinoJson::V701PB2::detail::MemberProxy<ArduinoJson::V701PB2::JsonDocument&, const char*>; typename ArduinoJson::V701PB2::detail::enable_if<(((! ArduinoJson::V701PB2::detail::ConverterNeedsWriteableRef<T>::value) && (! ArduinoJson::V701PB2::detail::is_same<T, char*>::value)) && (! ArduinoJson::V701PB2::detail::is_same<T, char>::value)), bool>::type = bool]'
MyProject.ino:11:28:   required from here
.../ArduinoJson/Variant/ConverterImpl.hpp:41:30: error: no matching function for call to 'canConvertFromJson(ArduinoJson::V701PB2::JsonVariantConst&, Point&)'
   41 |     return canConvertFromJson(src, dummy);  // Error here? See https://arduinojson.org/v7/unsupported-is/
      |            ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~

How to fix this error?

To allow JsonVariant::is<T>() to work with a custom T, you must define a function canConvertFromJson() like so:

bool canConvertFromJson(JsonVarianConst src, const Point&) {
  return src["x"].is<int>() && src["y"].is<int>();
}

The second parameter of canConvertFromJson() is required to trigger ADL but must not be used by the function.

How to support non-default-constructible types?

Before calling canConvertFromJson(), ArduinoJson creates an instance of the target type to pass a reference as a second argument. This requires that the type is default-constructible; otherwise, ArduinoJson wouldn’t know how to construct the instance.

Therefore, you cannot use canConvertFromJson() for non-default-constructible types. Instead, you must use a lower-level hook based on the specialization of Converter<T>, like so:

namespace ArduinoJson {
template <>
struct Converter<Point> {
  static Point checkJson(JsonVariantConst src) {
    return src["x"].is<int>() && src["y"].is<int>();
  }

  // (you'll most likely defined fromJson() too)
};
}

Of course, Point is default-constructible, but you get the idea, right?

See also