bool maybe_add(JSContext *cx, HandleObject self, const char *name, const char *value) {
  MOZ_ASSERT(is_instance(self));
  RootedString name_str(cx, JS_NewStringCopyN(cx, name, strlen(name)));
  if (!name_str) {
    return false;
  }
  RootedValue name_val(cx, JS::StringValue(name_str));

  RootedObject map(cx, detail::backing_map(self));
  bool has;
  if (!JS::MapHas(cx, map, name_val, &has)) {
    return false;
  }
  if (has) {
    return true;
  }

  RootedString value_str(cx, JS_NewStringCopyN(cx, value, strlen(value)));
  if (!value_str) {
    return false;
  }
  RootedValue value_val(cx, JS::StringValue(value_str));

  return detail::append_header_value(cx, self, name_val, value_val, "internal_maybe_add");
}
bool maybe_add(JSContext *cx, HandleObject self, const char *name, const char *value) {
  MOZ_ASSERT(is_instance(self));
  RootedString name_str(cx, JS_NewStringCopyN(cx, name, strlen(name)));
  if (!name_str) {
    return false;
  }
  RootedValue name_val(cx, JS::StringValue(name_str));

  RootedObject map(cx, detail::backing_map(self));
  bool has;
  if (!JS::MapHas(cx, map, name_val, &has)) {
    return false;
  }
  if (has) {
    return true;
  }

  RootedString value_str(cx, JS_NewStringCopyN(cx, value, strlen(value)));
  if (!value_str) {
    return false;
  }
  RootedValue value_val(cx, JS::StringValue(value_str));

  return detail::append_header_value(cx, self, name_val, value_val, "internal_maybe_add");
}