schema tree BUGFIX accessible tree fixes
diff --git a/src/parser_stmt.c b/src/parser_stmt.c
index 4c14501..5703ffe 100644
--- a/src/parser_stmt.c
+++ b/src/parser_stmt.c
@@ -746,7 +746,7 @@
             break;
         case LY_STMT_PATH:
             LY_CHECK_RET(lysp_stmt_text_field(ctx, child, LYEXT_SUBSTMT_PATH, 0, &str_path, Y_STR_ARG, &type->exts));
-            ret = ly_path_parse(PARSER_CTX(ctx), str_path, 0, LY_PATH_BEGIN_EITHER, LY_PATH_LREF_TRUE,
+            ret = ly_path_parse(PARSER_CTX(ctx), NULL, str_path, 0, LY_PATH_BEGIN_EITHER, LY_PATH_LREF_TRUE,
                                 LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_LEAFREF, &type->path);
             lydict_remove(PARSER_CTX(ctx), str_path);
             LY_CHECK_RET(ret);
diff --git a/src/parser_yang.c b/src/parser_yang.c
index 104786c..47833ab 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -2039,7 +2039,7 @@
             }
 
             LY_CHECK_RET(parse_text_field(ctx, in, LYEXT_SUBSTMT_PATH, 0, &str_path, Y_STR_ARG, &type->exts));
-            ret = ly_path_parse(ctx->ctx, str_path, 0, LY_PATH_BEGIN_EITHER, LY_PATH_LREF_TRUE,
+            ret = ly_path_parse(ctx->ctx, NULL, str_path, 0, LY_PATH_BEGIN_EITHER, LY_PATH_LREF_TRUE,
                                 LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_LEAFREF, &type->path);
             lydict_remove(ctx->ctx, str_path);
             LY_CHECK_RET(ret);
diff --git a/src/parser_yin.c b/src/parser_yin.c
index 89dc4cf..a3d208d 100644
--- a/src/parser_yin.c
+++ b/src/parser_yin.c
@@ -465,7 +465,7 @@
     const char *str_path;
 
     LY_CHECK_RET(yin_parse_simple_element(ctx, kw, &str_path, YIN_ARG_VALUE, Y_STR_ARG, &type->exts));
-    ret = ly_path_parse(ctx->xmlctx->ctx, str_path, 0, LY_PATH_BEGIN_EITHER, LY_PATH_LREF_TRUE,
+    ret = ly_path_parse(ctx->xmlctx->ctx, NULL, str_path, 0, LY_PATH_BEGIN_EITHER, LY_PATH_LREF_TRUE,
                         LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_LEAFREF, &type->path);
     lydict_remove(ctx->xmlctx->ctx, str_path);
     LY_CHECK_RET(ret);
diff --git a/src/path.c b/src/path.c
index 4017be7..7558f95 100644
--- a/src/path.c
+++ b/src/path.c
@@ -31,10 +31,13 @@
 #include "tree_schema_internal.h"
 #include "xpath.h"
 
+#define LOGVAL_P(CTX, CUR_NODE, CODE, FORMAT...) ly_vlog(CTX, (CUR_NODE) ? LY_VLOG_LYSC : LY_VLOG_NONE, CUR_NODE, CODE, ##FORMAT)
+
 /**
  * @brief Check predicate syntax.
  *
  * @param[in] ctx libyang context.
+ * @param[in] cur_node Current (original context) node.
  * @param[in] exp Parsed predicate.
  * @param[in,out] tok_idx Index in @p exp, is adjusted.
  * @param[in] prefix Prefix option.
@@ -42,8 +45,8 @@
  * @return LY_ERR value.
  */
 static LY_ERR
-ly_path_check_predicate(const struct ly_ctx *ctx, const struct lyxp_expr *exp, uint16_t *tok_idx, uint8_t prefix,
-                        uint8_t pred)
+ly_path_check_predicate(const struct ly_ctx *ctx, const struct lysc_node *cur_node, const struct lyxp_expr *exp,
+                        uint16_t *tok_idx, uint8_t prefix, uint8_t pred)
 {
     struct ly_set *set = NULL;
     uint32_t i;
@@ -64,8 +67,8 @@
                 /* check prefix based on the options */
                 name = strnstr(exp->expr + exp->tok_pos[*tok_idx], ":", exp->tok_len[*tok_idx]);
                 if ((prefix == LY_PATH_PREFIX_MANDATORY) && !name) {
-                    LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Prefix missing for \"%.*s\" in path.", exp->tok_len[*tok_idx],
-                           exp->expr + exp->tok_pos[*tok_idx]);
+                    LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Prefix missing for \"%.*s\" in path.", exp->tok_len[*tok_idx],
+                             exp->expr + exp->tok_pos[*tok_idx]);
                     goto error;
                 }
                 if (!name) {
@@ -80,8 +83,7 @@
                 for (i = 0; i < set->count; ++i) {
                     /* all the keys must be from the same module so this comparison should be fine */
                     if (!strncmp(set->objs[i], name, name_len) && !isalpha(((char *)set->objs[i])[name_len])) {
-                        LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Duplicate predicate key \"%.*s\" in path.",
-                               name_len, name);
+                        LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Duplicate predicate key \"%.*s\" in path.", name_len, name);
                         goto error;
                     }
                 }
@@ -143,8 +145,7 @@
                 for (i = 0; i < set->count; ++i) {
                     /* all the keys must be from the same module so this comparison should be fine */
                     if (!strncmp(set->objs[i], name, name_len) && !isalpha(((char *)set->objs[i])[name_len])) {
-                        LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Duplicate predicate key \"%.*s\" in path.",
-                               name_len, name);
+                        LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Duplicate predicate key \"%.*s\" in path.", name_len, name);
                         goto error;
                     }
                 }
@@ -161,8 +162,8 @@
                 /* FuncName */
                 LY_CHECK_GOTO(lyxp_check_token(ctx, exp, *tok_idx, LYXP_TOKEN_FUNCNAME), error);
                 if ((exp->tok_len[*tok_idx] != 7) || strncmp(exp->expr + exp->tok_pos[*tok_idx], "current", 7)) {
-                    LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Invalid function \"%.*s\" invocation in path.",
-                        exp->tok_len[*tok_idx], exp->expr + exp->tok_pos[*tok_idx]);
+                    LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Invalid function \"%.*s\" invocation in path.",
+                             exp->tok_len[*tok_idx], exp->expr + exp->tok_pos[*tok_idx]);
                     goto error;
                 }
                 ++(*tok_idx);
@@ -199,8 +200,8 @@
             } while (!lyxp_next_token(NULL, exp, tok_idx, LYXP_TOKEN_BRACK1));
 
         } else {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LY_VCODE_XP_INTOK, lyxp_print_token(exp->tokens[*tok_idx]),
-                   exp->expr + exp->tok_pos[*tok_idx]);
+            LOGVAL_P(ctx, cur_node, LY_VCODE_XP_INTOK, lyxp_print_token(exp->tokens[*tok_idx]),
+                     exp->expr + exp->tok_pos[*tok_idx]);
             goto error;
         }
     }
@@ -214,8 +215,8 @@
 }
 
 LY_ERR
-ly_path_parse(const struct ly_ctx *ctx, const char *str_path, size_t path_len, uint8_t begin, uint8_t lref,
-              uint8_t prefix, uint8_t pred, struct lyxp_expr **expr)
+ly_path_parse(const struct ly_ctx *ctx, const struct lysc_node *ctx_node, const char *str_path, size_t path_len,
+              uint8_t begin, uint8_t lref, uint8_t prefix, uint8_t pred, struct lyxp_expr **expr)
 {
     struct lyxp_expr *exp;
     uint16_t tok_idx;
@@ -250,23 +251,23 @@
 
         /* check prefix based on the options */
         if ((prefix == LY_PATH_PREFIX_MANDATORY) && !strnstr(exp->expr + exp->tok_pos[tok_idx], ":", exp->tok_len[tok_idx])) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Prefix missing for \"%.*s\" in path.", exp->tok_len[tok_idx],
-                   exp->expr + exp->tok_pos[tok_idx]);
+            LOGVAL_P(ctx, ctx_node, LYVE_XPATH, "Prefix missing for \"%.*s\" in path.", exp->tok_len[tok_idx],
+                     exp->expr + exp->tok_pos[tok_idx]);
             goto error;
         }
 
         ++tok_idx;
 
         /* Predicate* */
-        LY_CHECK_GOTO(ly_path_check_predicate(ctx, exp, &tok_idx, prefix, pred), error);
+        LY_CHECK_GOTO(ly_path_check_predicate(ctx, ctx_node, exp, &tok_idx, prefix, pred), error);
 
     /* '/' */
     } while (!lyxp_next_token(NULL, exp, &tok_idx, LYXP_TOKEN_OPER_PATH));
 
     /* trailing token check */
     if (exp->used > tok_idx) {
-        LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Unparsed characters \"%s\" left at the end of path.",
-               exp->expr + exp->tok_pos[tok_idx]);
+        LOGVAL_P(ctx, ctx_node, LYVE_XPATH, "Unparsed characters \"%s\" left at the end of path.",
+                 exp->expr + exp->tok_pos[tok_idx]);
         goto error;
     }
 
@@ -279,8 +280,8 @@
 }
 
 LY_ERR
-ly_path_parse_predicate(const struct ly_ctx *ctx, const char *str_path, size_t path_len, uint8_t prefix, uint8_t pred,
-                        struct lyxp_expr **expr)
+ly_path_parse_predicate(const struct ly_ctx *ctx, const struct lysc_node *cur_node, const char *str_path,
+                        size_t path_len, uint8_t prefix, uint8_t pred, struct lyxp_expr **expr)
 {
     struct lyxp_expr *exp;
     uint16_t tok_idx;
@@ -293,12 +294,12 @@
     LY_CHECK_GOTO(!exp, error);
     tok_idx = 0;
 
-    LY_CHECK_GOTO(ly_path_check_predicate(ctx, exp, &tok_idx, prefix, pred), error);
+    LY_CHECK_GOTO(ly_path_check_predicate(ctx, cur_node, exp, &tok_idx, prefix, pred), error);
 
     /* trailing token check */
     if (exp->used > tok_idx) {
-        LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Unparsed characters \"%s\" left at the end of predicate.",
-               exp->expr + exp->tok_pos[tok_idx]);
+        LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Unparsed characters \"%s\" left at the end of predicate.",
+                 exp->expr + exp->tok_pos[tok_idx]);
         goto error;
     }
 
@@ -314,6 +315,7 @@
  * @brief Parse prefix from a NameTest, if any, and node name, and return expected module of the node.
  *
  * @param[in] ctx libyang context.
+ * @param[in] cur_node Optional current (original context) node.
  * @param[in] cur_mod Module of the current (original context) node. Needed for ::LYD_SCHEMA.
  * @param[in] prev_ctx_node Previous context node. Needed for ::LYD_JSON.
  * @param[in] expr Parsed path.
@@ -328,9 +330,10 @@
  * @return LY_ERR value.
  */
 static LY_ERR
-ly_path_compile_prefix(const struct ly_ctx *ctx, const struct lys_module *cur_mod, const struct lysc_node *prev_ctx_node,
-                       const struct lyxp_expr *expr, uint16_t tok_idx, uint8_t lref, ly_clb_resolve_prefix resolve_prefix,
-                       void *prefix_data, LYD_FORMAT format, const struct lys_module **mod, const char **name, size_t *name_len)
+ly_path_compile_prefix(const struct ly_ctx *ctx, const struct lysc_node *cur_node, const struct lys_module *cur_mod,
+                       const struct lysc_node *prev_ctx_node, const struct lyxp_expr *expr, uint16_t tok_idx,
+                       uint8_t lref, ly_clb_resolve_prefix resolve_prefix, void *prefix_data, LYD_FORMAT format,
+                       const struct lys_module **mod, const char **name, size_t *name_len)
 {
     const char *ptr;
     size_t len;
@@ -345,12 +348,12 @@
     if (ptr) {
         *mod = resolve_prefix(ctx, expr->expr + expr->tok_pos[tok_idx], len, prefix_data);
         if (!*mod) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Prefix \"%.*s\" not found of a module in path.",
-                   len, expr->expr + expr->tok_pos[tok_idx]);
+            LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Prefix \"%.*s\" not found of a module in path.",
+                     len, expr->expr + expr->tok_pos[tok_idx]);
             return LY_EVALID;
         } else if (!(*mod)->implemented) {
             if (lref == LY_PATH_LREF_FALSE) {
-                LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Not implemented module \"%s\" in path.", (*mod)->name);
+                LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Not implemented module \"%s\" in path.", (*mod)->name);
                 return LY_EVALID;
             }
             lys_set_implemented_internal((struct lys_module *)*mod, 2);
@@ -386,10 +389,10 @@
 }
 
 LY_ERR
-ly_path_compile_predicate(const struct ly_ctx *ctx, const struct lys_module *cur_mod, const struct lysc_node *ctx_node,
-                          const struct lyxp_expr *expr, uint16_t *tok_idx, ly_clb_resolve_prefix resolve_prefix,
-                          void *prefix_data, LYD_FORMAT format, struct ly_path_predicate **predicates,
-                          enum ly_path_pred_type *pred_type)
+ly_path_compile_predicate(const struct ly_ctx *ctx, const struct lysc_node *cur_node, const struct lys_module *cur_mod,
+                          const struct lysc_node *ctx_node, const struct lyxp_expr *expr, uint16_t *tok_idx,
+                          ly_clb_resolve_prefix resolve_prefix, void *prefix_data, LYD_FORMAT format,
+                          struct ly_path_predicate **predicates, enum ly_path_pred_type *pred_type)
 {
     struct ly_path_predicate *p;
     const struct lysc_node *key;
@@ -409,26 +412,26 @@
 
     if (expr->tokens[*tok_idx] == LYXP_TOKEN_NAMETEST) {
         if (ctx_node->nodetype != LYS_LIST) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "List predicate defined for %s \"%s\" in path.",
-                   lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
+            LOGVAL_P(ctx, cur_node, LYVE_XPATH, "List predicate defined for %s \"%s\" in path.",
+                     lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
             return LY_EVALID;
         } else if (ctx_node->flags & LYS_KEYLESS) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "List predicate defined for keyless %s \"%s\" in path.",
-                   lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
+            LOGVAL_P(ctx, cur_node, LYVE_XPATH, "List predicate defined for keyless %s \"%s\" in path.",
+                     lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
             return LY_EVALID;
         }
 
         do {
             /* NameTest, find the key */
-            LY_CHECK_RET(ly_path_compile_prefix(ctx, cur_mod, ctx_node, expr, *tok_idx, LY_PATH_LREF_FALSE, resolve_prefix,
-                                                prefix_data, format, &mod, &name, &name_len));
+            LY_CHECK_RET(ly_path_compile_prefix(ctx, cur_node, cur_mod, ctx_node, expr, *tok_idx, LY_PATH_LREF_FALSE,
+                                                resolve_prefix, prefix_data, format, &mod, &name, &name_len));
             key = lys_find_child(ctx_node, mod, name, name_len, 0, LYS_GETNEXT_NOSTATECHECK);
             if (!key) {
-                LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Not found node \"%.*s\" in path.", name_len, name);
+                LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Not found node \"%.*s\" in path.", name_len, name);
                 return LY_ENOTFOUND;
             } else if ((key->nodetype != LYS_LEAF) || !(key->flags & LYS_KEY)) {
-                LOGVAL(ctx, LY_VLOG_LYSC, key, LYVE_XPATH, "Key expected instead of %s \"%s\" in path.",
-                       lys_nodetype2str(key->nodetype), key->name);
+                LOGVAL_P(ctx, cur_node ? cur_node : key, LYVE_XPATH, "Key expected instead of %s \"%s\" in path.",
+                         lys_nodetype2str(key->nodetype), key->name);
                 return LY_EVALID;
             }
             ++(*tok_idx);
@@ -465,8 +468,8 @@
         }
         if (LY_ARRAY_COUNT(*predicates) != key_count) {
             /* names (keys) are unique - it was checked when parsing */
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Predicate missing for a key of %s \"%s\" in path.",
-                   lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
+            LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Predicate missing for a key of %s \"%s\" in path.",
+                     lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
             ly_path_predicates_free(ctx, LY_PATH_PREDTYPE_LIST, NULL, *predicates);
             *predicates = NULL;
             return LY_EVALID;
@@ -474,8 +477,8 @@
 
     } else if (expr->tokens[*tok_idx] == LYXP_TOKEN_DOT) {
         if (ctx_node->nodetype != LYS_LEAFLIST) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Leaf-list predicate defined for %s \"%s\" in path.",
-                   lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
+            LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Leaf-list predicate defined for %s \"%s\" in path.",
+                     lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
             return LY_EVALID;
         }
         ++(*tok_idx);
@@ -500,12 +503,12 @@
     } else {
         assert(expr->tokens[*tok_idx] == LYXP_TOKEN_NUMBER);
         if (!(ctx_node->nodetype & (LYS_LEAFLIST | LYS_LIST))) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Positional predicate defined for %s \"%s\" in path.",
-                   lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
+            LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Positional predicate defined for %s \"%s\" in path.",
+                     lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
             return LY_EVALID;
         } else if (ctx_node->flags & LYS_CONFIG_W) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Positional predicate defined for configuration"
-                   " %s \"%s\" in path.", lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
+            LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Positional predicate defined for configuration %s \"%s\" in path.",
+                     lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
             return LY_EVALID;
         }
 
@@ -554,26 +557,26 @@
     }
 
     if (ctx_node->nodetype != LYS_LIST) {
-        LOGVAL(cur_node->module->ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "List predicate defined for %s \"%s\" in path.",
-               lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
+        LOGVAL_P(cur_node->module->ctx, cur_node, LYVE_XPATH, "List predicate defined for %s \"%s\" in path.",
+                 lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
         return LY_EVALID;
     } else if (ctx_node->flags & LYS_KEYLESS) {
-        LOGVAL(cur_node->module->ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "List predicate defined for keyless %s \"%s\" in path.",
-               lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
+        LOGVAL_P(cur_node->module->ctx, cur_node, LYVE_XPATH, "List predicate defined for keyless %s \"%s\" in path.",
+                 lys_nodetype2str(ctx_node->nodetype), ctx_node->name);
         return LY_EVALID;
     }
 
     do {
         /* NameTest, find the key */
-        LY_CHECK_RET(ly_path_compile_prefix(cur_node->module->ctx, cur_node->module, ctx_node, expr, *tok_idx,
+        LY_CHECK_RET(ly_path_compile_prefix(cur_node->module->ctx, cur_node, cur_node->module, ctx_node, expr, *tok_idx,
                                             LY_PATH_LREF_TRUE, resolve_prefix, prefix_data, format, &mod, &name, &name_len));
         key = lys_find_child(ctx_node, mod, name, name_len, 0, LYS_GETNEXT_NOSTATECHECK);
         if (!key) {
-            LOGVAL(cur_node->module->ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Not found node \"%.*s\" in path.", name_len, name);
+            LOGVAL_P(cur_node->module->ctx, cur_node, LYVE_XPATH, "Not found node \"%.*s\" in path.", name_len, name);
             return LY_EVALID;
         } else if ((key->nodetype != LYS_LEAF) || !(key->flags & LYS_KEY)) {
-            LOGVAL(cur_node->module->ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Key expected instead of %s \"%s\" in path.",
-                   lys_nodetype2str(key->nodetype), key->name);
+            LOGVAL_P(cur_node->module->ctx, cur_node, LYVE_XPATH, "Key expected instead of %s \"%s\" in path.",
+                     lys_nodetype2str(key->nodetype), key->name);
             return LY_EVALID;
         }
         ++(*tok_idx);
@@ -607,7 +610,7 @@
 
             /* go to parent */
             if (!node) {
-                LOGVAL(cur_node->module->ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Too many parent references in path.");
+                LOGVAL_P(cur_node->module->ctx, cur_node, LYVE_XPATH, "Too many parent references in path.");
                 return LY_EVALID;
             }
             node = lysc_data_parent(node);
@@ -624,12 +627,11 @@
 
             /* NameTest */
             assert(expr->tokens[*tok_idx] == LYXP_TOKEN_NAMETEST);
-            LY_CHECK_RET(ly_path_compile_prefix(cur_node->module->ctx, cur_node->module, node, expr, *tok_idx,
+            LY_CHECK_RET(ly_path_compile_prefix(cur_node->module->ctx, cur_node, cur_node->module, node, expr, *tok_idx,
                                                 LY_PATH_LREF_TRUE, resolve_prefix, prefix_data, format, &mod, &name, &name_len));
             node2 = lys_find_child(node, mod, name, name_len, 0, LYS_GETNEXT_NOSTATECHECK);
             if (!node2) {
-                LOGVAL(cur_node->module->ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Not found node \"%.*s\" in path.",
-                       name_len, name);
+                LOGVAL_P(cur_node->module->ctx, cur_node, LYVE_XPATH, "Not found node \"%.*s\" in path.", name_len, name);
                 return LY_EVALID;
             }
             node = node2;
@@ -638,8 +640,9 @@
 
         /* check the last target node */
         if (node->nodetype != LYS_LEAF) {
-            LOGVAL(cur_node->module->ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Leaf expected instead of %s \"%s\" in"
-                   " leafref predicate in path.", lys_nodetype2str(node->nodetype), node->name);
+            LOGVAL_P(cur_node->module->ctx, cur_node, LYVE_XPATH,
+                     "Leaf expected instead of %s \"%s\" in leafref predicate in path.",
+                     lys_nodetype2str(node->nodetype), node->name);
             return LY_EVALID;
         }
 
@@ -664,22 +667,24 @@
     LY_ERR ret = LY_SUCCESS;
     uint16_t tok_idx = 0;
     const struct lys_module *mod;
-    const struct lysc_node *node2, *cur_node;
+    const struct lysc_node *node2, *cur_node, *op;
     struct ly_path *p = NULL;
     int getnext_opts;
     const char *name;
     size_t name_len;
 
     assert(ctx);
-    assert((expr->tokens[tok_idx] == LYXP_TOKEN_OPER_PATH) || (lref == LY_PATH_LREF_FALSE) || ctx_node);
+    assert((lref == LY_PATH_LREF_FALSE) || ctx_node);
     assert((lref == LY_PATH_LREF_TRUE) || (lref == LY_PATH_LREF_FALSE));
     assert((oper == LY_PATH_OPER_INPUT) || (oper == LY_PATH_OPER_OUTPUT));
     assert((target == LY_PATH_TARGET_SINGLE) || (target == LY_PATH_TARGET_MANY));
 
-    if (lref == LY_PATH_LREF_TRUE) {
-        /* remember original context node */
-        cur_node = ctx_node;
-    }
+    /* find operation, if we are in any */
+    for (op = ctx_node; op && !(op->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF)); op = op->parent);
+
+    /* remember original context node */
+    cur_node = ctx_node;
+
     *path = NULL;
 
     if (oper == LY_PATH_OPER_OUTPUT) {
@@ -697,7 +702,7 @@
         /* relative path */
         while ((lref == LY_PATH_LREF_TRUE) && (expr->tokens[tok_idx] == LYXP_TOKEN_DDOT)) {
             if (!ctx_node) {
-                LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Too many parent references in path.");
+                LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Too many parent references in path.");
                 return LY_EVALID;
             }
 
@@ -717,20 +722,20 @@
     do {
         /* check last compiled inner node, whether it is uniquely identified (even key-less list) */
         if (p && (lref == LY_PATH_LREF_FALSE) && (p->node->nodetype == LYS_LIST) && !p->predicates) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Predicate missing for %s \"%s\" in path.",
-                   lys_nodetype2str(p->node->nodetype), p->node->name);
+            LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Predicate missing for %s \"%s\" in path.",
+                     lys_nodetype2str(p->node->nodetype), p->node->name);
             return LY_EVALID;
         }
 
         /* get module and node name */
-        LY_CHECK_GOTO(ret = ly_path_compile_prefix(ctx, cur_mod, ctx_node, expr, tok_idx, lref, resolve_prefix,
+        LY_CHECK_GOTO(ret = ly_path_compile_prefix(ctx, cur_node, cur_mod, ctx_node, expr, tok_idx, lref, resolve_prefix,
                                                    prefix_data, format, &mod, &name, &name_len), cleanup);
         ++tok_idx;
 
         /* find the next node */
         node2 = lys_find_child(ctx_node, mod, name, name_len, 0, getnext_opts);
-        if (!node2) {
-            LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Not found node \"%.*s\" in path.", name_len, name);
+        if (!node2 || ((node2->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF)) && (node2 != op))) {
+            LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Not found node \"%.*s\" in path.", name_len, name);
             ret = LY_EVALID;
             goto cleanup;
         }
@@ -744,8 +749,8 @@
         if (lref == LY_PATH_LREF_TRUE) {
             ret = ly_path_compile_predicate_leafref(ctx_node, cur_node, expr, &tok_idx, resolve_prefix, prefix_data, format);
         } else {
-            ret = ly_path_compile_predicate(ctx, cur_mod, ctx_node, expr, &tok_idx, resolve_prefix, prefix_data, format,
-                                            &p->predicates, &p->pred_type);
+            ret = ly_path_compile_predicate(ctx, cur_node, cur_mod, ctx_node, expr, &tok_idx, resolve_prefix,
+                                            prefix_data, format, &p->predicates, &p->pred_type);
         }
         LY_CHECK_GOTO(ret, cleanup);
     } while (!lyxp_next_token(NULL, expr, &tok_idx, LYXP_TOKEN_OPER_PATH));
@@ -753,8 +758,8 @@
     /* check last compiled node */
     if ((lref == LY_PATH_LREF_FALSE) && (target == LY_PATH_TARGET_SINGLE)
             && (p->node->nodetype & (LYS_LIST | LYS_LEAFLIST)) && !p->predicates) {
-        LOGVAL(ctx, LY_VLOG_NONE, NULL, LYVE_XPATH, "Predicate missing for %s \"%s\" in path.",
-               lys_nodetype2str(p->node->nodetype), p->node->name);
+        LOGVAL_P(ctx, cur_node, LYVE_XPATH, "Predicate missing for %s \"%s\" in path.",
+                 lys_nodetype2str(p->node->nodetype), p->node->name);
         return LY_EVALID;
     }
 
diff --git a/src/path.h b/src/path.h
index a60fdc6..2e32f91 100644
--- a/src/path.h
+++ b/src/path.h
@@ -93,6 +93,7 @@
  * @brief Parse path into XPath token structure and perform all additional checks.
  *
  * @param[in] ctx libyang context.
+ * @param[in] ctx_node Optional context node.
  * @param[in] str_path Path to parse.
  * @param[in] path_len Length of @p str_path.
  * @param[in] begin Begin option (@ref path_begin_options).
@@ -102,13 +103,14 @@
  * @param[out] expr Parsed path.
  * @return LY_ERR value.
  */
-LY_ERR ly_path_parse(const struct ly_ctx *ctx, const char *str_path, size_t path_len, uint8_t begin, uint8_t lref,
-                     uint8_t prefix, uint8_t pred, struct lyxp_expr **expr);
+LY_ERR ly_path_parse(const struct ly_ctx *ctx, const struct lysc_node *ctx_node, const char *str_path, size_t path_len,
+                     uint8_t begin, uint8_t lref, uint8_t prefix, uint8_t pred, struct lyxp_expr **expr);
 
 /**
  * @brief Parse predicate into XPath token structure and perform all additional checks.
  *
  * @param[in] ctx libyang context.
+ * @param[in] cur_node Optional current (original context) node.
  * @param[in] str_path Path to parse.
  * @param[in] path_len Length of @p str_path.
  * @param[in] prefix Prefix option (@ref path_prefix_options).
@@ -116,8 +118,8 @@
  * @param[out] expr Parsed path.
  * @return LY_ERR value.
  */
-LY_ERR ly_path_parse_predicate(const struct ly_ctx *ctx, const char *str_path, size_t path_len, uint8_t prefix,
-                               uint8_t pred, struct lyxp_expr **expr);
+LY_ERR ly_path_parse_predicate(const struct ly_ctx *ctx, const struct lysc_node *cur_node, const char *str_path,
+                               size_t path_len, uint8_t prefix, uint8_t pred, struct lyxp_expr **expr);
 
 /**
  * @defgroup path_oper_options Path operation options.
@@ -142,7 +144,7 @@
  *
  * @param[in] ctx libyang context.
  * @param[in] cur_mod Module of the current (original context) node. Used for nodes without prefix for ::LYD_SCHEMA format.
- * @param[in] ctx_node Context node. Can be NULL for absolute paths.
+ * @param[in] ctx_node Optional context node.
  * @param[in] expr Parsed path.
  * @param[in] lref Lref option (@ref path_lref_options).
  * @param[in] oper Oper option (@ref path_oper_options).
@@ -161,6 +163,7 @@
  * @brief Compile predicate into ly_path_predicate structure. Only simple predicates (not leafref) are supported.
  *
  * @param[in] ctx libyang context.
+ * @param[in] cur_node Optional current (original context) node.
  * @param[in] cur_mod Module of the current (original context) node. Used for nodes without prefix for ::LYD_SCHEMA format.
  * @param[in] ctx_node Context node, node for which the predicate is defined.
  * @param[in] expr Parsed path.
@@ -172,7 +175,7 @@
  * @param[out] pred_type Type of the compiled predicate(s).
  * @return LY_ERR value.
  */
-LY_ERR ly_path_compile_predicate(const struct ly_ctx *ctx, const struct lys_module *cur_mod,
+LY_ERR ly_path_compile_predicate(const struct ly_ctx *ctx, const struct lysc_node *cur_node, const struct lys_module *cur_mod,
                                  const struct lysc_node *ctx_node, const struct lyxp_expr *expr, uint16_t *tok_idx,
                                  ly_clb_resolve_prefix resolve_prefix, void *prefix_data, LYD_FORMAT format,
                                  struct ly_path_predicate **predicates, enum ly_path_pred_type *pred_type);
diff --git a/src/plugins_types.c b/src/plugins_types.c
index 429cf96..2b64a20 100644
--- a/src/plugins_types.c
+++ b/src/plugins_types.c
@@ -1493,6 +1493,8 @@
 
     /* init */
     *err = NULL;
+    ctx_scnode = (options & (LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_INCOMPLETE_DATA)) ?
+                 (struct lysc_node *)context_node : ((struct lyd_node *)context_node)->schema;
 
     if ((options & LY_TYPE_OPTS_SCHEMA) && (options & LY_TYPE_OPTS_INCOMPLETE_DATA)) {
         /* we have incomplete schema tree, so we are actually just storing the original value for future validation */
@@ -1525,16 +1527,14 @@
     prefixes = ly_type_get_prefixes(ctx, value, value_len, resolve_prefix, parser);
 
     /* parse the value */
-    ret = ly_path_parse(ctx, value, value_len, LY_PATH_BEGIN_ABSOLUTE, LY_PATH_LREF_FALSE, LY_PATH_PREFIX_MANDATORY,
-                        LY_PATH_PRED_SIMPLE, &exp);
+    ret = ly_path_parse(ctx, ctx_scnode, value, value_len, LY_PATH_BEGIN_ABSOLUTE, LY_PATH_LREF_FALSE,
+                        LY_PATH_PREFIX_MANDATORY, LY_PATH_PRED_SIMPLE, &exp);
     if (ret) {
         erc = asprintf(&errmsg, "Invalid instance-identifier \"%.*s\" value - syntax error.", (int)value_len, value);
         goto error;
     }
 
     /* resolve it on schema tree */
-    ctx_scnode = (options & (LY_TYPE_OPTS_SCHEMA | LY_TYPE_OPTS_INCOMPLETE_DATA)) ?
-                 (struct lysc_node *)context_node : ((struct lyd_node *)context_node)->schema;
     ret = ly_path_compile(ctx, ctx_scnode->module, NULL, exp, LY_PATH_LREF_FALSE, lysc_is_output(ctx_scnode) ?
                           LY_PATH_OPER_OUTPUT : LY_PATH_OPER_INPUT, LY_PATH_TARGET_SINGLE, ly_type_stored_prefixes_clb,
                           prefixes, format, &path);
diff --git a/src/tree_data.c b/src/tree_data.c
index 5b2d7f7..9dde20e 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -587,12 +587,12 @@
     struct ly_path_predicate *predicates = NULL;
 
     /* parse keys */
-    LY_CHECK_GOTO(ret = ly_path_parse_predicate(schema->module->ctx, keys, keys_len, LY_PATH_PREFIX_OPTIONAL,
+    LY_CHECK_GOTO(ret = ly_path_parse_predicate(schema->module->ctx, NULL, keys, keys_len, LY_PATH_PREFIX_OPTIONAL,
                                                 LY_PATH_PRED_KEYS, &expr), cleanup);
 
     /* compile them */
-    LY_CHECK_GOTO(ret = ly_path_compile_predicate(schema->module->ctx, NULL, schema, expr, &exp_idx, lydjson_resolve_prefix,
-                                                  NULL, LYD_JSON, &predicates, &pred_type), cleanup);
+    LY_CHECK_GOTO(ret = ly_path_compile_predicate(schema->module->ctx, NULL, NULL, schema, expr, &exp_idx,
+                                                  lydjson_resolve_prefix, NULL, LYD_JSON, &predicates, &pred_type), cleanup);
 
     /* create the list node */
     LY_CHECK_GOTO(ret = lyd_create_list(schema, predicates, node), cleanup);
@@ -1156,7 +1156,7 @@
     }
 
     /* parse path */
-    LY_CHECK_GOTO(ret = ly_path_parse(ctx, path, strlen(path), LY_PATH_BEGIN_EITHER, LY_PATH_LREF_FALSE,
+    LY_CHECK_GOTO(ret = ly_path_parse(ctx, NULL, path, strlen(path), LY_PATH_BEGIN_EITHER, LY_PATH_LREF_FALSE,
                                       LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_SIMPLE, &exp), cleanup);
 
     /* compile path */
diff --git a/src/tree_schema_compile.c b/src/tree_schema_compile.c
index ca53a39..1b99187 100644
--- a/src/tree_schema_compile.c
+++ b/src/tree_schema_compile.c
@@ -6810,9 +6810,17 @@
     struct lysc_when **when = NULL;
     struct lysc_must *musts = NULL;
     LY_ERR ret = LY_SUCCESS;
+    const struct lysc_node *op;
 
     memset(&tmp_set, 0, sizeof tmp_set);
     opts = LYXP_SCNODE_SCHEMA;
+    if (node->flags & LYS_CONFIG_R) {
+        for (op = node->parent; op && !(op->nodetype & (LYS_RPC | LYS_ACTION)); op = op->parent);
+        if (op) {
+            /* we are actually in output */
+            opts = LYXP_SCNODE_OUTPUT;
+        }
+    }
 
     switch (node->nodetype) {
     case LYS_CONTAINER:
@@ -6932,7 +6940,7 @@
 static LY_ERR
 lys_compile_unres_leafref(struct lysc_ctx *ctx, const struct lysc_node *node, struct lysc_type_leafref *lref)
 {
-    const struct lysc_node *target = NULL;
+    const struct lysc_node *target = NULL, *siter;
     struct ly_path *p;
     struct lysc_type *type;
 
@@ -6965,8 +6973,9 @@
     ctx->path[1] = '\0';
 
     /* check config */
-    if (lref->require_instance && (node->flags & LYS_CONFIG_W)) {
-        if (target->flags & LYS_CONFIG_R) {
+    if (lref->require_instance) {
+        for (siter = node->parent; siter && !(siter->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF)); siter = siter->parent);
+        if (!siter && (node->flags & LYS_CONFIG_W) && (target->flags & LYS_CONFIG_R)) {
             LOGVAL(ctx->ctx, LY_VLOG_LYSC, node, LYVE_REFERENCE, "Invalid leafref path \"%s\" - target is supposed"
                    " to represent configuration data (as the leafref does), but it does not.", lref->path->expr);
             return LY_EVALID;
diff --git a/src/xpath.c b/src/xpath.c
index 55a0f6b..533e2da 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -773,6 +773,7 @@
         new->ctx = set->ctx;
         new->ctx_node = set->ctx_node;
         new->root_type = set->root_type;
+        new->context_op = set->context_op;
         new->local_mod = set->local_mod;
         new->tree = set->tree;
         new->format = set->format;
@@ -5360,14 +5361,15 @@
  *
  * @param[in] node Node to check.
  * @param[in] root_type XPath root node type.
+ * @param[in] context_op XPath operation parent.
  * @param[in] node_name Node name in the dictionary to move to, NULL for any node.
  * @param[in] moveto_mod Expected module of the node, NULL for any.
  * @return LY_ERR (LY_ENOT if node does not match, LY_EINCOMPLETE on unresolved when,
  * LY_EINVAL if netither node nor any children match)
  */
 static LY_ERR
-moveto_node_check(const struct lyd_node *node, enum lyxp_node_type root_type, const char *node_name,
-                  const struct lys_module *moveto_mod)
+moveto_node_check(const struct lyd_node *node, enum lyxp_node_type root_type, const struct lysc_node *context_op,
+                  const char *node_name, const struct lys_module *moveto_mod)
 {
     /* module check */
     if (moveto_mod && (node->schema->module != moveto_mod)) {
@@ -5377,6 +5379,8 @@
     /* context check */
     if ((root_type == LYXP_NODE_ROOT_CONFIG) && (node->schema->flags & LYS_CONFIG_R)) {
         return LY_EINVAL;
+    } else if (context_op && (node->schema->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF)) && (node->schema != context_op)) {
+        return LY_EINVAL;
     }
 
     /* name check */
@@ -5398,13 +5402,14 @@
  *
  * @param[in] node Schema node to check.
  * @param[in] root_type XPath root node type.
+ * @param[in] context_op XPath operation parent.
  * @param[in] node_name Node name in the dictionary to move to, NULL for any nodes.
  * @param[in] moveto_mod Expected module of the node, NULL for any.
  * @return LY_ERR (LY_ENOT if node does not match, LY_EINVAL if neither node nor any children match)
  */
 static LY_ERR
-moveto_scnode_check(const struct lysc_node *node, enum lyxp_node_type root_type, const char *node_name,
-                    const struct lys_module *moveto_mod)
+moveto_scnode_check(const struct lysc_node *node, enum lyxp_node_type root_type, const struct lysc_node *context_op,
+                    const char *node_name, const struct lys_module *moveto_mod)
 {
     /* module check */
     if (moveto_mod && (node->module != moveto_mod)) {
@@ -5414,6 +5419,8 @@
     /* context check */
     if ((root_type == LYXP_NODE_ROOT_CONFIG) && (node->flags & LYS_CONFIG_R)) {
         return LY_EINVAL;
+    } else if (context_op && (node->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF)) && (node != context_op)) {
+        return LY_EINVAL;
     }
 
     /* name check */
@@ -5464,7 +5471,7 @@
         }
 
         for (sub = siblings; sub; sub = sub->next) {
-            rc = moveto_node_check(sub, set->root_type, ncname, mod);
+            rc = moveto_node_check(sub, set->root_type, set->context_op, ncname, mod);
             if (rc == LY_SUCCESS) {
                 if (!replaced) {
                     set_replace_node(set, sub, 0, LYXP_NODE_ELEM, i);
@@ -5520,6 +5527,10 @@
     if ((set->root_type == LYXP_NODE_ROOT_CONFIG) && (scnode->flags & LYS_CONFIG_R)) {
         lyxp_set_free_content(set);
         goto cleanup;
+    }  else if (set->context_op && (scnode->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF))
+            && (scnode != set->context_op)) {
+        lyxp_set_free_content(set);
+        goto cleanup;
     }
 
     /* create specific data instance if needed */
@@ -5624,7 +5635,7 @@
                 iter = NULL;
                 /* module may not be implemented */
                 while (mod->implemented && (iter = lys_getnext(iter, NULL, mod->compiled, getnext_opts))) {
-                    if (!moveto_scnode_check(iter, set->root_type, ncname, mod)) {
+                    if (!moveto_scnode_check(iter, set->root_type, set->context_op, ncname, mod)) {
                         idx = lyxp_set_scnode_insert_node(set, iter, LYXP_NODE_ELEM);
                         /* we need to prevent these nodes from being considered in this moveto */
                         if ((idx < orig_used) && (idx > i)) {
@@ -5645,7 +5656,7 @@
         } else if (set->val.scnodes[i].type == LYXP_NODE_ELEM) {
             iter = NULL;
             while ((iter = lys_getnext(iter, start_parent, NULL, getnext_opts))) {
-                if (!moveto_scnode_check(iter, set->root_type, ncname, (mod ? mod : set->local_mod))) {
+                if (!moveto_scnode_check(iter, set->root_type, set->context_op, ncname, (mod ? mod : set->local_mod))) {
                     idx = lyxp_set_scnode_insert_node(set, iter, LYXP_NODE_ELEM);
                     if ((idx < orig_used) && (idx > i)) {
                         set->val.scnodes[idx].in_ctx = 2;
@@ -5705,7 +5716,7 @@
         /* TREE DFS */
         start = set->val.nodes[i].node;
         for (elem = next = start; elem; elem = next) {
-            rc = moveto_node_check(elem, set->root_type, ncname, mod);
+            rc = moveto_node_check(elem, set->root_type, set->context_op, ncname, mod);
             if (!rc) {
                 /* add matching node into result set */
                 set_insert_node(&ret_set, elem, 0, LYXP_NODE_ELEM, ret_set.used);
@@ -5800,7 +5811,7 @@
                 goto next_iter;
             }
 
-            rc = moveto_scnode_check(elem, set->root_type, ncname, mod);
+            rc = moveto_scnode_check(elem, set->root_type, set->context_op, ncname, mod);
             if (!rc) {
                 if ((idx = lyxp_set_scnode_dup_node_check(set, elem, LYXP_NODE_ELEM, i)) > -1) {
                     set->val.scnodes[idx].in_ctx = 1;
@@ -6902,17 +6913,17 @@
     prev_lo = ly_log_options(0);
 
     /* parse the predicate(s) */
-    LY_CHECK_GOTO(ret = ly_path_parse_predicate(scnode->module->ctx, exp->expr + exp->tok_pos[*tok_idx], pred_len,
+    LY_CHECK_GOTO(ret = ly_path_parse_predicate(scnode->module->ctx, scnode, exp->expr + exp->tok_pos[*tok_idx], pred_len,
                                                 LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_SIMPLE, &exp2), cleanup);
 
     /* compile */
     switch (format) {
     case LYD_SCHEMA:
-        ret = ly_path_compile_predicate(scnode->module->ctx, scnode->module, scnode, exp2, &pred_idx, lys_resolve_prefix,
-                                        scnode->module, LYD_SCHEMA, predicates, pred_type);
+        ret = ly_path_compile_predicate(scnode->module->ctx, scnode, scnode->module, scnode, exp2, &pred_idx,
+                                        lys_resolve_prefix, scnode->module, LYD_SCHEMA, predicates, pred_type);
         break;
     case LYD_JSON:
-        ret = ly_path_compile_predicate(scnode->module->ctx, scnode->module, scnode, exp2, &pred_idx,
+        ret = ly_path_compile_predicate(scnode->module->ctx, scnode, scnode->module, scnode, exp2, &pred_idx,
                                         lydjson_resolve_prefix, NULL, LYD_JSON, predicates, pred_type);
         break;
     case LYD_XML:
@@ -7050,8 +7061,7 @@
             if (i == -1) {
                 path = lysc_path(set->ctx_scnode, LYSC_PATH_LOG, NULL, 0);
                 LOGWRN(set->ctx, "Schema node \"%.*s\" not found (%.*s) with context node \"%s\".",
-                       exp->tok_len[*tok_idx], &exp->expr[exp->tok_pos[*tok_idx]],
-                       exp->tok_pos[*tok_idx] + exp->tok_len[*tok_idx], exp->expr, path);
+                       ncname_len, ncname, ncname - exp->expr, exp->expr, path);
                 free(path);
             }
         } else {
@@ -8305,19 +8315,25 @@
 static enum lyxp_node_type
 lyxp_get_root_type(const struct lyd_node *ctx_node, const struct lysc_node *ctx_scnode, int options)
 {
+    const struct lysc_node *op;
+
     if (options & LYXP_SCNODE_ALL) {
-        if (options & LYXP_SCNODE) {
+        for (op = ctx_scnode; op && !(op->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF)); op = op->parent);
+
+        if (op || (options & LYXP_SCNODE)) {
             /* general root that can access everything */
             return LYXP_NODE_ROOT;
         } else if (!ctx_scnode || (ctx_scnode->flags & LYS_CONFIG_W)) {
             /* root context node can access only config data (because we said so, it is unspecified) */
             return LYXP_NODE_ROOT_CONFIG;
-        } else {
-            return LYXP_NODE_ROOT;
         }
+        return LYXP_NODE_ROOT;
     }
 
-    if (!ctx_node || (ctx_node->schema->flags & LYS_CONFIG_W)) {
+    op = ctx_node ? ctx_node->schema : NULL;
+    for (; op && !(op->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF)); op = op->parent);
+
+    if (!ctx_node || (!op && (ctx_node->schema->flags & LYS_CONFIG_W))) {
         /* root context node can access only config data (because we said so, it is unspecified) */
         return LYXP_NODE_ROOT_CONFIG;
     }
@@ -8350,6 +8366,9 @@
     set->ctx = local_mod->ctx;
     set->ctx_node = ctx_node;
     set->root_type = lyxp_get_root_type(real_ctx_node, NULL, options);
+    for (set->context_op = ctx_node->schema;
+         set->context_op && !(set->context_op->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF));
+         set->context_op = set->context_op->parent);
     set->local_mod = local_mod;
     set->tree = tree;
     set->format = format;
@@ -8618,6 +8637,9 @@
     set->ctx = ctx;
     set->ctx_scnode = ctx_scnode;
     set->root_type = lyxp_get_root_type(NULL, real_ctx_scnode, options);
+    for (set->context_op = ctx_scnode;
+         set->context_op && !(set->context_op->nodetype & (LYS_RPC | LYS_ACTION | LYS_NOTIF));
+         set->context_op = set->context_op->parent);
     set->local_mod = local_mod;
     set->format = format;
 
diff --git a/src/xpath.h b/src/xpath.h
index 72858dd..a79ea82 100644
--- a/src/xpath.h
+++ b/src/xpath.h
@@ -256,6 +256,7 @@
         const struct lysc_node *ctx_scnode;
     };
     enum lyxp_node_type root_type;
+    const struct lysc_node *context_op;
     const struct lys_module *local_mod;
     const struct lyd_node *tree;
     LYD_FORMAT format;
diff --git a/tests/utests/schema/test_schema.c b/tests/utests/schema/test_schema.c
index 9a03332..d8da7d6 100644
--- a/tests/utests/schema/test_schema.c
+++ b/tests/utests/schema/test_schema.c
@@ -102,6 +102,7 @@
 void test_date(void **state);
 void test_revisions(void **state);
 void test_typedef(void **state);
+void test_accessible_tree(void **state);
 
 /* test_schema_stmts.c */
 void test_identity(void **state);
@@ -115,6 +116,7 @@
         cmocka_unit_test_setup_teardown(test_date, logger_setup, logger_teardown),
         cmocka_unit_test_setup_teardown(test_revisions, logger_setup, logger_teardown),
         cmocka_unit_test_setup_teardown(test_typedef, logger_setup, logger_teardown),
+        cmocka_unit_test_setup_teardown(test_accessible_tree, logger_setup, logger_teardown),
 
         /** test_schema_stmts.c */
         cmocka_unit_test_setup_teardown(test_identity, logger_setup, logger_teardown),
diff --git a/tests/utests/schema/test_schema_common.c b/tests/utests/schema/test_schema_common.c
index 5b75b9e..9e70bdc 100644
--- a/tests/utests/schema/test_schema_common.c
+++ b/tests/utests/schema/test_schema_common.c
@@ -314,3 +314,390 @@
     *state = NULL;
     ly_ctx_destroy(ctx, NULL);
 }
+
+void
+test_accessible_tree(void **state)
+{
+    *state = test_accessible_tree;
+
+    struct ly_ctx *ctx = NULL;
+    const char *str;
+
+    assert_int_equal(LY_SUCCESS, ly_ctx_new(NULL, LY_CTX_DISABLE_SEARCHDIRS, &ctx));
+    logbuf_clean();
+
+    /* config -> config */
+    str =
+        "module a {"
+            "namespace urn:a;"
+            "prefix a;"
+            "container cont {"
+                "leaf l {"
+                    "type empty;"
+                "}"
+            "}"
+            "container cont2 {"
+                "leaf l2 {"
+                    "must ../../cont/l;"
+                    "type leafref {"
+                        "path /cont/l;"
+                    "}"
+                "}"
+            "}"
+        "}";
+    assert_int_equal(lys_parse_mem(ctx, str, LYS_IN_YANG, NULL), LY_SUCCESS);
+    logbuf_assert("");
+
+    /* config -> state leafref */
+    str =
+        "module b {"
+            "namespace urn:a;"
+            "prefix a;"
+            "container cont {"
+                "config false;"
+                "leaf l {"
+                    "type empty;"
+                "}"
+            "}"
+            "container cont2 {"
+                "leaf l2 {"
+                    "type leafref {"
+                        "path /cont/l;"
+                    "}"
+                "}"
+            "}"
+        "}";
+    assert_int_equal(lys_parse_mem(ctx, str, LYS_IN_YANG, NULL), LY_EVALID);
+    logbuf_assert("Invalid leafref path \"/cont/l\" - target is supposed to represent configuration data"
+        " (as the leafref does), but it does not. /b:cont2/l2");
+    logbuf_clean();
+
+    /* config -> state must */
+    str =
+        "module b {"
+            "namespace urn:a;"
+            "prefix a;"
+            "container cont {"
+                "config false;"
+                "leaf l {"
+                    "type empty;"
+                "}"
+            "}"
+            "container cont2 {"
+                "leaf l2 {"
+                    "must ../../cont/l;"
+                    "type empty;"
+                "}"
+            "}"
+        "}";
+    assert_int_equal(lys_parse_mem(ctx, str, LYS_IN_YANG, NULL), LY_SUCCESS);
+    logbuf_assert("Schema node \"l\" not found (../../cont/) with context node \"/b:cont2/l2\".");
+    logbuf_clean();
+
+    /* state -> config */
+    str =
+        "module c {"
+            "namespace urn:a;"
+            "prefix a;"
+            "container cont {"
+                "leaf l {"
+                    "type empty;"
+                "}"
+            "}"
+            "container cont2 {"
+                "config false;"
+                "leaf l2 {"
+                    "must ../../cont/l;"
+                    "type leafref {"
+                        "path /cont/l;"
+                    "}"
+                "}"
+            "}"
+        "}";
+    assert_int_equal(lys_parse_mem(ctx, str, LYS_IN_YANG, NULL), LY_SUCCESS);
+    logbuf_assert("");
+
+    /* notif -> state */
+    str =
+        "module d {"
+            "namespace urn:a;"
+            "prefix a;"
+            "container cont {"
+                "config false;"
+                "leaf l {"
+                    "type empty;"
+                "}"
+            "}"
+            "notification notif {"
+                "leaf l2 {"
+                    "must ../../cont/l;"
+                    "type leafref {"
+                        "path /cont/l;"
+                    "}"
+                "}"
+            "}"
+        "}";
+    assert_int_equal(lys_parse_mem(ctx, str, LYS_IN_YANG, NULL), LY_SUCCESS);
+    logbuf_assert("");
+
+    /* notif -> notif */
+    str =
+        "module e {"
+            "namespace urn:a;"
+            "prefix a;"
+            "notification notif {"
+                "leaf l {"
+                    "type empty;"
+                "}"
+                "leaf l2 {"
+                    "must ../../notif/l;"
+                    "type leafref {"
+                        "path /notif/l;"
+                    "}"
+                "}"
+            "}"
+        "}";
+    assert_int_equal(lys_parse_mem(ctx, str, LYS_IN_YANG, NULL), LY_SUCCESS);
+    logbuf_assert("");
+
+    /* rpc input -> state */
+    str =
+        "module f {"
+            "namespace urn:a;"
+            "prefix a;"
+            "container cont {"
+                "config false;"
+                "leaf l {"
+                    "type empty;"
+                "}"
+            "}"
+            "rpc rp {"
+                "input {"
+                    "leaf l2 {"
+                        "must ../../cont/l;"
+                        "type leafref {"
+                            "path /cont/l;"
+                        "}"
+                    "}"
+                "}"
+            "}"
+        "}";
+    assert_int_equal(lys_parse_mem(ctx, str, LYS_IN_YANG, NULL), LY_SUCCESS);
+    logbuf_assert("");
+
+    /* rpc input -> rpc input */
+    str =
+        "module g {"
+            "namespace urn:a;"
+            "prefix a;"
+            "rpc rp {"
+                "input {"
+                    "leaf l {"
+                        "type empty;"
+                    "}"
+                    "leaf l2 {"
+                        "must ../l;"
+                        "type leafref {"
+                            "path /rp/l;"
+                        "}"
+                    "}"
+                "}"
+            "}"
+        "}";
+    assert_int_equal(lys_parse_mem(ctx, str, LYS_IN_YANG, NULL), LY_SUCCESS);
+    logbuf_assert("");
+
+    /* rpc input -> rpc output leafref */
+    str =
+        "module h {"
+            "namespace urn:a;"
+            "prefix a;"
+            "rpc rp {"
+                "input {"
+                    "leaf l2 {"
+                        "type leafref {"
+                            "path /rp/l;"
+                        "}"
+                    "}"
+                "}"
+                "output {"
+                    "leaf l {"
+                        "type empty;"
+                    "}"
+                "}"
+            "}"
+        "}";
+    assert_int_equal(lys_parse_mem(ctx, str, LYS_IN_YANG, NULL), LY_EVALID);
+    logbuf_assert("Not found node \"l\" in path. /h:rp/l2");
+    logbuf_clean();
+
+    /* rpc input -> rpc output must */
+    str =
+        "module h {"
+            "namespace urn:a;"
+            "prefix a;"
+            "rpc rp {"
+                "input {"
+                    "leaf l2 {"
+                        "must ../l;"
+                        "type empty;"
+                    "}"
+                "}"
+                "output {"
+                    "leaf l {"
+                        "type empty;"
+                    "}"
+                "}"
+            "}"
+        "}";
+    assert_int_equal(lys_parse_mem(ctx, str, LYS_IN_YANG, NULL), LY_SUCCESS);
+    logbuf_assert("Schema node \"l\" not found (../) with context node \"/h:rp/l2\".");
+    logbuf_clean();
+
+    /* rpc input -> notif leafref */
+    str =
+        "module i {"
+            "namespace urn:a;"
+            "prefix a;"
+            "rpc rp {"
+                "input {"
+                    "leaf l2 {"
+                        "type leafref {"
+                            "path ../../notif/l;"
+                        "}"
+                    "}"
+                "}"
+            "}"
+            "notification notif {"
+                "leaf l {"
+                    "type empty;"
+                "}"
+            "}"
+        "}";
+    assert_int_equal(lys_parse_mem(ctx, str, LYS_IN_YANG, NULL), LY_EVALID);
+    logbuf_assert("Not found node \"notif\" in path. /i:rp/l2");
+    logbuf_clean();
+
+    /* rpc input -> notif must */
+    str =
+        "module i {"
+            "namespace urn:a;"
+            "prefix a;"
+            "rpc rp {"
+                "input {"
+                    "leaf l2 {"
+                        "must /notif/l;"
+                        "type empty;"
+                    "}"
+                "}"
+            "}"
+            "notification notif {"
+                "leaf l {"
+                    "type empty;"
+                "}"
+            "}"
+        "}";
+    assert_int_equal(lys_parse_mem(ctx, str, LYS_IN_YANG, NULL), LY_SUCCESS);
+    logbuf_assert("Schema node \"l\" not found (/notif/) with context node \"/i:rp/l2\".");
+    logbuf_clean();
+
+    /* action output -> state */
+    str =
+        "module j {"
+            "yang-version 1.1;"
+            "namespace urn:a;"
+            "prefix a;"
+            "container cont {"
+                "list ll {"
+                    "key k;"
+                    "leaf k {"
+                        "type string;"
+                    "}"
+                    "action act {"
+                        "output {"
+                            "leaf l2 {"
+                                "must /cont/l;"
+                                "type leafref {"
+                                    "path ../../../l;"
+                                "}"
+                            "}"
+                        "}"
+                    "}"
+                "}"
+                "leaf l {"
+                    "config false;"
+                    "type empty;"
+                "}"
+            "}"
+        "}";
+    assert_int_equal(lys_parse_mem(ctx, str, LYS_IN_YANG, NULL), LY_SUCCESS);
+    logbuf_assert("");
+
+    /* action output -> action input leafref */
+    str =
+        "module k {"
+            "yang-version 1.1;"
+            "namespace urn:a;"
+            "prefix a;"
+            "container cont {"
+                "list ll {"
+                    "key k;"
+                    "leaf k {"
+                        "type string;"
+                    "}"
+                    "action act {"
+                        "input {"
+                            "leaf l {"
+                                "type empty;"
+                            "}"
+                        "}"
+                        "output {"
+                            "leaf l2 {"
+                                "type leafref {"
+                                    "path ../l;"
+                                "}"
+                            "}"
+                        "}"
+                    "}"
+                "}"
+            "}"
+        "}";
+    assert_int_equal(lys_parse_mem(ctx, str, LYS_IN_YANG, NULL), LY_EVALID);
+    logbuf_assert("Not found node \"l\" in path. /k:cont/ll/act/l2");
+    logbuf_clean();
+
+    /* action output -> action input must */
+    str =
+        "module k {"
+            "yang-version 1.1;"
+            "namespace urn:a;"
+            "prefix a;"
+            "container cont {"
+                "list ll {"
+                    "key k;"
+                    "leaf k {"
+                        "type string;"
+                    "}"
+                    "action act {"
+                        "input {"
+                            "leaf l {"
+                                "type empty;"
+                            "}"
+                        "}"
+                        "output {"
+                            "leaf l2 {"
+                                "must /cont/ll/act/l;"
+                                "type empty;"
+                            "}"
+                        "}"
+                    "}"
+                "}"
+            "}"
+        "}";
+    assert_int_equal(lys_parse_mem(ctx, str, LYS_IN_YANG, NULL), LY_SUCCESS);
+    logbuf_assert("Schema node \"l\" not found (/cont/ll/act/) with context node \"/k:cont/ll/act/l2\".");
+    logbuf_clean();
+
+    *state = NULL;
+    ly_ctx_destroy(ctx, NULL);
+}
diff --git a/tests/utests/schema/test_schema_stmts.c b/tests/utests/schema/test_schema_stmts.c
index 97ad697..99137c7 100644
--- a/tests/utests/schema/test_schema_stmts.c
+++ b/tests/utests/schema/test_schema_stmts.c
@@ -154,7 +154,6 @@
     ly_ctx_destroy(ctx, NULL);
 }
 
-
 void
 test_feature(void **state)
 {
diff --git a/tests/utests/schema/test_tree_schema_compile.c b/tests/utests/schema/test_tree_schema_compile.c
index e7c82e7..bade042 100644
--- a/tests/utests/schema/test_tree_schema_compile.c
+++ b/tests/utests/schema/test_tree_schema_compile.c
@@ -1739,17 +1739,17 @@
     /* invalid paths */
     assert_int_equal(LY_EVALID, lys_parse_mem(ctx, "module aa {namespace urn:aa;prefix aa;container a {leaf target2 {type uint8;}}"
                                         "leaf ref1 {type leafref {path ../a/invalid;}}}", LYS_IN_YANG, &mod));
-    logbuf_assert("Not found node \"invalid\" in path.");
+    logbuf_assert("Not found node \"invalid\" in path. /aa:ref1");
     assert_int_equal(LY_EVALID, lys_parse_mem(ctx, "module bb {namespace urn:bb;prefix bb;container a {leaf target2 {type uint8;}}"
                                         "leaf ref1 {type leafref {path ../../toohigh;}}}", LYS_IN_YANG, &mod));
-    logbuf_assert("Too many parent references in path.");
+    logbuf_assert("Too many parent references in path. /bb:ref1");
     assert_int_equal(LY_EVALID, lys_parse_mem(ctx, "module cc {namespace urn:cc;prefix cc;container a {leaf target2 {type uint8;}}"
                                         "leaf ref1 {type leafref {path /a:invalid;}}}", LYS_IN_YANG, &mod));
-    logbuf_assert("Prefix \"a\" not found of a module in path.");
+    logbuf_assert("Prefix \"a\" not found of a module in path. /cc:ref1");
     assert_int_equal(LY_EVALID, lys_parse_mem(ctx, "module dd {namespace urn:dd;prefix dd;leaf target1 {type string;}"
                                         "container a {leaf target2 {type uint8;}} leaf ref1 {type leafref {"
                                         "path '/a[target2 = current()/../target1]/target2';}}}", LYS_IN_YANG, &mod));
-    logbuf_assert("List predicate defined for container \"a\" in path.");
+    logbuf_assert("List predicate defined for container \"a\" in path. /dd:ref1");
     assert_int_equal(LY_EVALID, lys_parse_mem(ctx, "module ee {namespace urn:ee;prefix ee;container a {leaf target2 {type uint8;}}"
                                         "leaf ref1 {type leafref {path /a!invalid;}}}", LYS_IN_YANG, &mod));
     logbuf_assert("Invalid character 0x21 ('!'), perhaps \"a\" is supposed to be a function call.");
@@ -1799,14 +1799,14 @@
                                         "leaf ifname{type leafref{ path \"../interface/name\";}}"
                                         "leaf address {type leafref{ path \"/interface[x:name=current()/../ifname]/ip\";}}}",
                                         LYS_IN_YANG, &mod));
-    logbuf_assert("Prefix \"x\" not found of a module in path.");
+    logbuf_assert("Prefix \"x\" not found of a module in path. /pp:address");
 
     assert_int_equal(LY_EVALID, lys_parse_mem(ctx, "module qq {namespace urn:qq;prefix qq;"
                                         "list interface{key name;leaf name{type string;}leaf ip {type string;}}"
                                         "leaf ifname{type leafref{ path \"../interface/name\";}}"
                                         "leaf address {type leafref{ path \"/interface[id=current()/../ifname]/ip\";}}}",
                                         LYS_IN_YANG, &mod));
-    logbuf_assert("Not found node \"id\" in path.");
+    logbuf_assert("Not found node \"id\" in path. /qq:address");
 
     assert_int_equal(LY_EVALID, lys_parse_mem(ctx, "module rr {namespace urn:rr;prefix rr;"
                                         "list interface{key name;leaf name{type string;}leaf ip {type string;}}"
@@ -1862,32 +1862,32 @@
                                         "leaf ifname{type leafref{ path \"../interface/name\";}}"
                                         "leaf address {type leafref{ path \"/interface[name=current()/../x:ifname]/ip\";}}}",
                                         LYS_IN_YANG, &mod));
-    logbuf_assert("Prefix \"x\" not found of a module in path.");
+    logbuf_assert("Prefix \"x\" not found of a module in path. /yy:address");
 
     assert_int_equal(LY_EVALID, lys_parse_mem(ctx, "module zz {namespace urn:zz;prefix zz;"
                                         "list interface{key name;leaf name{type string;}leaf ip {type string;}}"
                                         "leaf ifname{type leafref{ path \"../interface/name\";}}"
                                         "leaf address {type leafref{ path \"/interface[name=current()/../xxx]/ip\";}}}",
                                         LYS_IN_YANG, &mod));
-    logbuf_assert("Not found node \"xxx\" in path.");
+    logbuf_assert("Not found node \"xxx\" in path. /zz:address");
 
     assert_int_equal(LY_EVALID, lys_parse_mem(ctx, "module zza {namespace urn:zza;prefix zza;"
                                         "list interface{key name;leaf name{type string;}leaf ip {type string;}}"
                                         "leaf ifname{type leafref{ path \"../interface/name\";}}container c;"
                                         "leaf address {type leafref{ path \"/interface[name=current()/../c]/ip\";}}}",
                                         LYS_IN_YANG, &mod));
-    logbuf_assert("Leaf expected instead of container \"c\" in leafref predicate in path.");
+    logbuf_assert("Leaf expected instead of container \"c\" in leafref predicate in path. /zza:address");
 
     assert_int_equal(LY_EVALID, lys_parse_mem(ctx, "module zzb {namespace urn:zzb;prefix zzb;"
                                         "list interface{key name;leaf name{type string;}leaf ip {type string;}container c;}"
                                         "leaf ifname{type leafref{ path \"../interface/name\";}}"
                                         "leaf address {type leafref{ path \"/interface[c=current()/../ifname]/ip\";}}}",
                                         LYS_IN_YANG, &mod));
-    logbuf_assert("Key expected instead of container \"c\" in path.");
+    logbuf_assert("Key expected instead of container \"c\" in path. /zzb:address");
 
     assert_int_equal(LY_EVALID, lys_parse_mem(ctx, "module zzc {namespace urn:zzc;prefix zzc;"
                                         "leaf source {type leafref {path \"../target\";}default true;}}", LYS_IN_YANG, &mod));
-    logbuf_assert("Not found node \"target\" in path.");
+    logbuf_assert("Not found node \"target\" in path. /zzc:source");
 
     assert_int_equal(LY_EVALID, lys_parse_mem(ctx, "module zzd {namespace urn:zzd;prefix zzd;"
                                         "leaf source {type leafref {path \"../target\";}default true;}"