data parsers BUGFIX memory leaks
diff --git a/src/parser_json.c b/src/parser_json.c
index 776c65b..da255a0 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -954,7 +954,7 @@
     if (dynamic) {
         free((char *)value);
     }
-    LY_CHECK_ERR_RET(ret, ly_free_val_prefs(lydctx->jsonctx->ctx, val_prefs), ret);
+    LY_CHECK_RET(ret);
 
     if (*status_p == LYJSON_OBJECT || *status_p == LYJSON_OBJECT_EMPTY) {
         /* process children */
diff --git a/src/parser_lyb.c b/src/parser_lyb.c
index fdc9257..9395a13 100644
--- a/src/parser_lyb.c
+++ b/src/parser_lyb.c
@@ -503,7 +503,7 @@
 
         /* value */
         ret = lyb_read_string(&value, 0, lybctx);
-        LY_CHECK_GOTO(ret, cleanup);
+        LY_CHECK_ERR_GOTO(ret, ly_free_val_prefs(lybctx->ctx, val_prefs), cleanup);
         dynamic = 1;
 
         /* attr2 is always changed to the created attribute */
@@ -517,7 +517,6 @@
         module_name = NULL;
         free(name);
         name = NULL;
-        val_prefs = NULL;
         assert(!dynamic);
         value = NULL;
 
@@ -536,7 +535,6 @@
     if (dynamic) {
         free(value);
     }
-    ly_free_val_prefs(lybctx->ctx, val_prefs);
     if (ret) {
         lyd_free_attr_siblings(lybctx->ctx, *attr);
         *attr = NULL;
@@ -745,7 +743,7 @@
 
         /* parse value */
         ret = lyb_read_string(&value, 0, lybctx->lybctx);
-        LY_CHECK_GOTO(ret, cleanup);
+        LY_CHECK_ERR_GOTO(ret, ly_free_val_prefs(ctx, val_prefs), cleanup);
         dynamic = 1;
 
         /* create node */
@@ -879,7 +877,6 @@
     if (dynamic) {
         free(value);
     }
-    ly_free_val_prefs(ctx, val_prefs);
 
     lyd_free_meta_siblings(meta);
     lyd_free_attr_siblings(ctx, attr);
diff --git a/src/tree_data.c b/src/tree_data.c
index 1159387..1b59493 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -706,13 +706,13 @@
     }
 
     opaq = calloc(1, sizeof *opaq);
-    LY_CHECK_ERR_RET(!opaq, LOGMEM(ctx), LY_EMEM);
+    LY_CHECK_ERR_RET(!opaq, LOGMEM(ctx); ly_free_val_prefs(ctx, val_prefs), LY_EMEM);
 
     opaq->prev = (struct lyd_node *)opaq;
-
+    opaq->val_prefs = val_prefs;
+    opaq->format = format;
     LY_CHECK_GOTO(ret = lydict_insert(ctx, name, name_len, &opaq->name), finish);
 
-    opaq->format = format;
     if (pref_len) {
         LY_CHECK_GOTO(ret = lydict_insert(ctx, prefix, pref_len, &opaq->prefix.id), finish);
     }
@@ -720,7 +720,6 @@
         LY_CHECK_GOTO(ret = lydict_insert(ctx, module_key, module_key_len, &opaq->prefix.module_ns), finish);
     }
 
-    opaq->val_prefs = val_prefs;
     if (dynamic && *dynamic) {
         LY_CHECK_GOTO(ret = lydict_insert_zc(ctx, (char *)value, &opaq->value), finish);
         *dynamic = 0;
@@ -2218,7 +2217,11 @@
     }
 
     at = calloc(1, sizeof *at);
-    LY_CHECK_ERR_RET(!at, LOGMEM(ctx), LY_EMEM);
+    LY_CHECK_ERR_RET(!at, LOGMEM(ctx); ly_free_val_prefs(ctx, val_prefs), LY_EMEM);
+    at->hint = value_hint;
+    at->format = format;
+    at->val_prefs = val_prefs;
+
     LY_CHECK_GOTO(ret = lydict_insert(ctx, name, name_len, &at->name), finish);
     if (dynamic && *dynamic) {
         ret = lydict_insert_zc(ctx, (char *)value, &at->value);
@@ -2228,9 +2231,6 @@
         LY_CHECK_GOTO(ret = lydict_insert(ctx, value, value_len, &at->value), finish);
     }
 
-    at->hint = value_hint;
-    at->format = format;
-    at->val_prefs = val_prefs;
     if (prefix_len) {
         LY_CHECK_GOTO(ret = lydict_insert(ctx, prefix, prefix_len, &at->prefix.id), finish);
     }
diff --git a/src/tree_data_free.c b/src/tree_data_free.c
index 333c5d6..409b507 100644
--- a/src/tree_data_free.c
+++ b/src/tree_data_free.c
@@ -22,6 +22,18 @@
 #include "tree_data_internal.h"
 #include "plugins_types.h"
 
+void
+ly_free_val_prefs(const struct ly_ctx *ctx, struct ly_prefix *val_prefs)
+{
+    LY_ARRAY_COUNT_TYPE u;
+
+    LY_ARRAY_FOR(val_prefs, u) {
+        FREE_STRING(ctx, val_prefs[u].id);
+        FREE_STRING(ctx, val_prefs[u].module_ns);
+    }
+    LY_ARRAY_FREE(val_prefs);
+}
+
 static void
 lyd_free_meta(struct lyd_meta *meta, ly_bool siblings)
 {
@@ -80,7 +92,6 @@
 lyd_free_attr(const struct ly_ctx *ctx, struct lyd_attr *attr, ly_bool siblings)
 {
     struct lyd_attr *iter;
-    LY_ARRAY_COUNT_TYPE u;
 
     LY_CHECK_ARG_RET(NULL, ctx, );
     if (!attr) {
@@ -114,11 +125,7 @@
         attr = iter;
         iter = iter->next;
 
-        LY_ARRAY_FOR(attr->val_prefs, u) {
-            FREE_STRING(ctx, attr->val_prefs[u].id);
-            FREE_STRING(ctx, attr->val_prefs[u].module_ns);
-        }
-        LY_ARRAY_FREE(attr->val_prefs);
+        ly_free_val_prefs(ctx, attr->val_prefs);
         FREE_STRING(ctx, attr->name);
         FREE_STRING(ctx, attr->value);
         FREE_STRING(ctx, attr->prefix.id);
@@ -139,18 +146,6 @@
     lyd_free_attr(ctx, attr, 1);
 }
 
-void
-ly_free_val_prefs(const struct ly_ctx *ctx, struct ly_prefix *val_prefs)
-{
-    LY_ARRAY_COUNT_TYPE u;
-
-    LY_ARRAY_FOR(val_prefs, u) {
-        FREE_STRING(ctx, val_prefs[u].id);
-        FREE_STRING(ctx, val_prefs[u].module_ns);
-    }
-    LY_ARRAY_FREE(val_prefs);
-}
-
 /**
  * @brief Free Data (sub)tree.
  * @param[in] node Data node to be freed.
diff --git a/src/tree_data_internal.h b/src/tree_data_internal.h
index bbd2692..d5bf168 100644
--- a/src/tree_data_internal.h
+++ b/src/tree_data_internal.h
@@ -172,7 +172,7 @@
  * @param[in,out] dynamic Flag if @p value is dynamically allocated, is adjusted when @p value is consumed.
  * @param[in] value_hint [Value hint](@ref lydvalueparseopts) from the parser regarding the value type.
  * @param[in] format Input format of @p value and @p ns.
- * @param[in] val_prefs Possible value prefixes, array is spent.
+ * @param[in] val_prefs Possible value prefixes, array is spent (even in case the function fails).
  * @param[in] prefix Element prefix.
  * @param[in] pref_len Length of @p prefix, must be set correctly.
  * @param[in] module_key Mandatory key to reference module, can be namespace or name.
@@ -273,7 +273,7 @@
  * @param[in,out] dynamic Flag if @p value is dynamically allocated, is adjusted when @p value is consumed.
  * @param[in] value_hint [Value hint](@ref lydvalueparseopts) from the parser regarding the value type.
  * @param[in] format Input format of @p value and @p ns.
- * @param[in] val_prefs Possible value prefixes, array is spent.
+ * @param[in] val_prefs Possible value prefixes, array is spent (even in case the function fails).
  * @param[in] prefix Attribute prefix.
  * @param[in] prefix_len Attribute prefix length.
  * @param[in] module_key Mandatory key to reference module, can be namespace or name.