# Using must condition under a leaf is causing internal error

**URL:** https://dmap-community.ductus.global/t/using-must-condition-under-a-leaf-is-causing-internal-error/2940
**Category:** YANG
**Created:** [February 24, 2020, 6:04am UTC](https://dmap-community.ductus.global/t/using-must-condition-under-a-leaf-is-causing-internal-error/2940 "2020-02-24T06:04:41Z")
**Posts on this page:** 17
**Page:** 1

<div class="post-metadata">

### Author: ![arun\_kumar](https://avatars.discourse-cdn.com/v4/letter/a/258eb7/32.png) [@arun\_kumar](https://dmap-community.ductus.global/u/arun_kumar)
#### Post date: [February 24, 2020, 6:04am UTC](https://dmap-community.ductus.global/t/using-must-condition-under-a-leaf-is-causing-internal-error/2940/1 "2020-02-24T06:04:42Z")

</div>

```auto
  grouping sample_grouping_1 {
    description "sample";
    leaf sampleleaf_1 {
      type leafref {
        path "../../../h1/h2_list/h2_key";
      }
      mandatory true;
    }
  }

```

then under this other grouping

```auto
  grouping sample_grouping_2 {
    uses sample_grouping_1;
    leaf sample_leaf_2 {
      type int32 {
        range "1..9600";
      }
      must 'deref(current())../sampleleaf_1/one_attribute_under_h2key = "EXTERNAL"';
      default 30;
    }
  }

```

With this, I get internal error while I try to compile the yangs,  
My question is , is the syntax I use legal in the first place, The deref comparison is being done across groupings, so should it involve additional syntax.

The path provided for the sample\_leaf\_1 is correct,so no issues there.

Thanks for the investment,  
Arun kumar Bhattar

---

<div class="post-metadata">

### Author: ![mvf](https://yyz2.discourse-cdn.com/flex010/user_avatar/dmap-community.ductus.global/mvf/32/182_2.png) [@mvf](https://dmap-community.ductus.global/u/mvf)
#### Post date: [February 24, 2020, 9:55am UTC](https://dmap-community.ductus.global/t/using-must-condition-under-a-leaf-is-causing-internal-error/2940/2 "2020-02-24T09:55:33Z")

</div>

The XPath function `deref()` should be applied to a node that is either an instance-identifier or a leafref, I’m assuming you inteded to apply it to `sampleleaf_1`, but you applied it to `current()`. Moreover, I would say `h2_key` is the key leaf of your `h2_list`, hence the `one_attribute_under_h2key` is more likely a sibling of `h2_key`, not its child. So probably your must statement should look like

```auto
     must 'deref(../sampleleaf_1)/../one_attribute_under_h2key = "EXTERNAL"';

```

Note also that `current()` should not be needed in this context.

---

<div class="post-metadata">

### Author: ![arun\_kumar](https://avatars.discourse-cdn.com/v4/letter/a/258eb7/32.png) [@arun\_kumar](https://dmap-community.ductus.global/u/arun_kumar)
#### Post date: [February 24, 2020, 1:44pm UTC](https://dmap-community.ductus.global/t/using-must-condition-under-a-leaf-is-causing-internal-error/2940/3 "2020-02-24T13:44:01Z")

</div>

Hi @mvf,  
Thank you for your pointing out my mistake.  
I have made changes as mentioned above, and now I get this error:

error: The ‘must’ expression should have a tailf:dependency. If is doesn’t, it will be checked for every commit

I do not understand exactly what is causing this issue. Please recommend.  
Thanks alot.

---

<div class="post-metadata">

### Author: ![mvf](https://yyz2.discourse-cdn.com/flex010/user_avatar/dmap-community.ductus.global/mvf/32/182_2.png) [@mvf](https://dmap-community.ductus.global/u/mvf)
#### Post date: [February 25, 2020, 8:30am UTC](https://dmap-community.ductus.global/t/using-must-condition-under-a-leaf-is-causing-internal-error/2940/4 "2020-02-25T08:30:41Z")

</div>

Have a look at the `dependency` extension and its description, either in `tailf-common.yang` or in `tailf_yang_extensions` man page in the documentation. Briefly, the message means that ConfD is not able to infer dependencies for the must statement and needs you to state them explicitly.

---

<div class="post-metadata">

### Author: ![arun\_kumar](https://avatars.discourse-cdn.com/v4/letter/a/258eb7/32.png) [@arun\_kumar](https://dmap-community.ductus.global/u/arun_kumar)
#### Post date: [February 25, 2020, 6:04pm UTC](https://dmap-community.ductus.global/t/using-must-condition-under-a-leaf-is-causing-internal-error/2940/5 "2020-02-25T18:04:41Z")

</div>

I was successfully able to fix the issue by adding a tailf:dependency. However, I would like to know if there is any way in which I could avoid importing the tailf-common.yang.

I am trying to look at possible ways to solving issue without importing the tailf-common.yang file

---

<div class="post-metadata">

### Author: ![mvf](https://yyz2.discourse-cdn.com/flex010/user_avatar/dmap-community.ductus.global/mvf/32/182_2.png) [@mvf](https://dmap-community.ductus.global/u/mvf)
#### Post date: [February 26, 2020, 6:41am UTC](https://dmap-community.ductus.global/t/using-must-condition-under-a-leaf-is-causing-internal-error/2940/6 "2020-02-26T06:41:17Z")

</div>

Sounds like you are looking for annotations - that’s the tool that lets you add `tailf:...` statements to a node without touching the original module. You write another YANG module (by convention it is named XXX-ann, i.e. if the main YANG file is `my-module.yang`, the annotation file is `my-module-ann.yang` - but it’s nothing more than a convention) that contains only statements `tailf:annotate-module`, `tailf:annotate-statement`, or `tailf:annotate`; usually the last one is more convenient, but since you are using groupings, maybe the first two are more handy. This file is then used when compiling `my-module.yang` with `-a my-module-ann.yang` - have a look at `confdc` man page.

There are some examples how those three statements should be used, read their description in `tailf-common.yang` or in the `tailf_yang_extensions` man page. Let me know if you can’t make them work.

---

<div class="post-metadata">

### Author: ![arun\_kumar](https://avatars.discourse-cdn.com/v4/letter/a/258eb7/32.png) [@arun\_kumar](https://dmap-community.ductus.global/u/arun_kumar)
#### Post date: [February 27, 2020, 12:21pm UTC](https://dmap-community.ductus.global/t/using-must-condition-under-a-leaf-is-causing-internal-error/2940/7 "2020-02-27T12:21:52Z")

</div>

I have added the tailf:dependency this way (in the annotation file)  
tailf:annotate “/a:a1/b:vehicles/b:cars/b:car/b:engine” {  
tailf:validate vp1  
{  
tailf:dependency ‘…/…/…/b:buses/b:bus/b:bus\_engine’;  
}  
}

b:bus\_engine is a leaf and the b:engine is a container  
I am compiling the annotation file and the yang file together using --annotation file tag. However, I still get the “The ‘must’ expression should have a tailf:dependency. If is doesn’t, it will be checked for every commit” error

---

<div class="post-metadata">

### Author: ![mvf](https://yyz2.discourse-cdn.com/flex010/user_avatar/dmap-community.ductus.global/mvf/32/182_2.png) [@mvf](https://dmap-community.ductus.global/u/mvf)
#### Post date: [February 27, 2020, 2:35pm UTC](https://dmap-community.ductus.global/t/using-must-condition-under-a-leaf-is-causing-internal-error/2940/8 "2020-02-27T14:35:44Z")

</div>

You need to annotate the `must` statement, so you have to use the combination of `tailf:annotate-module` and `tailf:annotate-statement` - the statement `tailf:annotate` can be used only to annotate data nodes, I believe. I did not notice this when writing the previous reply.

---

<div class="post-metadata">

### Author: ![arun\_kumar](https://avatars.discourse-cdn.com/v4/letter/a/258eb7/32.png) [@arun\_kumar](https://dmap-community.ductus.global/u/arun_kumar)
#### Post date: [March 2, 2020, 9:18am UTC](https://dmap-community.ductus.global/t/using-must-condition-under-a-leaf-is-causing-internal-error/2940/9 "2020-03-02T09:18:06Z")

</div>

I have tried doing it the following way --\>

tailf:annotate-module “module1”{  
tailf:annotate-statement grouping [name = ‘grouping\_inside\_module1’]{  
tailf:annotate-statement leaf[name=‘leaf\_inside\_the\_above\_grouping’] {  
tailf:dependency ‘…/leaf\_in\_a\_different\_grouping\_with\_type\_as\_leafref’;  
}  
}  
}

I see this error:

module1-ann.yang:86:34: error: unterminated statement for keyword “annotate-module”  
module1-ann.yang:86:34: error: unterminated statement for keyword “annotate-module”  
module1.yang:707: error: The ‘must’ expression should have a tailf:dependency. If is doesn’t, it will be checked for every commit.  
module1.yang:707: error: The ‘must’ expression should have a tailf:dependency. If is doesn’t, it will be checked for every commit.  
Generating .fxs file “module1-aug-npt.fxs”  
module1.yang:707: error: The ‘must’ expression should have a tailf:dependency. If is doesn’t, it will be checked for every commit.  
module1.yang:707: error: The ‘must’ expression should have a tailf:dependency. If is doesn’t, it will be checked for every commit.  
module1-ann.yang:86:34: error: unterminated statement for keyword “annotate-module”  
module1-ann.yang:86:34: error: unterminated statement for keyword “annotate-module”

Please help

---

<div class="post-metadata">

### Author: ![mvf](https://yyz2.discourse-cdn.com/flex010/user_avatar/dmap-community.ductus.global/mvf/32/182_2.png) [@mvf](https://dmap-community.ductus.global/u/mvf)
#### Post date: [March 3, 2020, 9:52am UTC](https://dmap-community.ductus.global/t/using-must-condition-under-a-leaf-is-causing-internal-error/2940/10 "2020-03-03T09:52:04Z")

</div>

I guess it should look something like this:

```auto
  tailf:annotate-module "module1" {
    tailf:annotate-statement grouping [name = 'grouping_inside_module1']{
      tailf:annotate-statement leaf[name='leaf_inside_the_above_grouping'] {
        tailf:annotate-statement must {
          tailf:dependency '../leaf_in_a_different_grouping_with_type_as_leafref';
        }
      }
    }
  }

```

Note one more `annotate-statement` for the must statement itself.

---

<div class="post-metadata">

### Author: ![per](https://avatars.discourse-cdn.com/v4/letter/p/9f8e36/32.png) [@per](https://dmap-community.ductus.global/u/per)
#### Post date: [March 3, 2020, 10:30am UTC](https://dmap-community.ductus.global/t/using-must-condition-under-a-leaf-is-causing-internal-error/2940/11 "2020-03-03T10:30:37Z")

</div>

Also watch the whitespace - there mustn’t be any space between the statement name and the predicate, nor around the ‘=’ in the predicate, and you have both in your ‘grouping’ annotation - this is the reason for your “unterminated statement” errors. I.e. it should be

```auto
  tailf:annotate-module "module1" {
    tailf:annotate-statement grouping[name='grouping_inside_module1'] {
      tailf:annotate-statement leaf[name='leaf_inside_the_above_grouping'] {
        tailf:annotate-statement must {
          tailf:dependency '../leaf_in_a_different_grouping_with_type_as_leafref';
        }
      }
    }
  }

```

(A space before ‘{’ isn’t required, but improves readability IMHO.)

Edit: I guess it would be a good idea if you showed the relevant part of the module being annotated - for starters, it is “unusual” that you have to use `tailf:dependency` with a `must` expression, perhaps you have some unintentional problem with the syntax of it.

---

<div class="post-metadata">

### Author: ![arun\_kumar](https://avatars.discourse-cdn.com/v4/letter/a/258eb7/32.png) [@arun\_kumar](https://dmap-community.ductus.global/u/arun_kumar)
#### Post date: [March 3, 2020, 11:40am UTC](https://dmap-community.ductus.global/t/using-must-condition-under-a-leaf-is-causing-internal-error/2940/12 "2020-03-03T11:40:47Z")

</div>

> [@per](#):
>
> tailf:annotate-statement must {

This is the module in the yang file →   
grouping grouping\_inside\_module1 {  
uses different\_grouping;

```
            leaf leaf_inside_the_above_grouping {
                    type int32 {
            range "1..3600";
                    }
             must 'deref(../leaf_in_a_different_grouping_with_type_as_leafref)/../leaf_needed_to_be_compared = "EXTERNAL"'{
            //tailf:dependency '../leaf_in_a_different_grouping_with_type_as_leafref';

```

}

When I un-comment the tailf dependency, I get the desired behavior. I am trying to achieve the same behavior by annotating that particular leaf in the corresponding annotation file.

With the above comments, I to write the annotation file, but I get an internal error.

tailf:annotate-module “module1”{  
tailf:annotate-statement grouping[name=‘grouping\_inside\_module1’]{  
tailf:annotate-statement leaf[name=‘leaf\_inside\_the\_above\_grouping’] {  
tailf:annotate-statement must {  
tailf:dependency ‘…/leaf\_in\_a\_different\_grouping\_with\_type\_as\_leafref’;  
}  
}  
}  
}

---

<div class="post-metadata">

### Author: ![per](https://avatars.discourse-cdn.com/v4/letter/p/9f8e36/32.png) [@per](https://dmap-community.ductus.global/u/per)
#### Post date: [March 3, 2020, 12:29pm UTC](https://dmap-community.ductus.global/t/using-must-condition-under-a-leaf-is-causing-internal-error/2940/13 "2020-03-03T12:29:52Z")

</div>

> [@arun\_kumar](#):
>
> ```auto
> must 'deref(../leaf_in_a_different_grouping_with_type_as_leafref)/../leaf_needed_to_be_compared = "EXTERNAL"'{
> 
> ```

OK, it seems the compiler can’t calculate the dependencies when `deref()` is used - i.e. you _do_  
need a `tailf:dependency` statement.

> [@arun\_kumar](#):
>
> ```auto
> tailf:annotate-module “module1”{
> tailf:annotate-statement grouping[name=‘grouping_inside_module1’]{
> tailf:annotate-statement leaf[name=‘leaf_inside_the_above_grouping’] {
> tailf:annotate-statement must {
> tailf:dependency ‘…/leaf_in_a_different_grouping_with_type_as_leafref’;
> }
> }
> }
> }
> 
> ```

Looks OK, except for the _three_ leading dots in `…/leaf_in_a_different_grouping_with_type_as_leafref`, should of course be two - do you actually have three? When I try that, I get the expected “bad argument value” from the compiler, but with two dots it’s fine, no errors or warnings.

Exactly how do you run the compiler? And what version of ConfD are you using?

---

<div class="post-metadata">

### Author: ![arun\_kumar](https://avatars.discourse-cdn.com/v4/letter/a/258eb7/32.png) [@arun\_kumar](https://dmap-community.ductus.global/u/arun_kumar)
#### Post date: [March 3, 2020, 5:34pm UTC](https://dmap-community.ductus.global/t/using-must-condition-under-a-leaf-is-causing-internal-error/2940/14 "2020-03-03T17:34:55Z")

</div>

It is a correction, I have made a mistake while typing it here, it is actually two dots itself

---

<div class="post-metadata">

### Author: ![arun\_kumar](https://avatars.discourse-cdn.com/v4/letter/a/258eb7/32.png) [@arun\_kumar](https://dmap-community.ductus.global/u/arun_kumar)
#### Post date: [March 3, 2020, 5:53pm UTC](https://dmap-community.ductus.global/t/using-must-condition-under-a-leaf-is-causing-internal-error/2940/15 "2020-03-03T17:53:28Z")

</div>

I need a a tailf:dependency statement, otherwise I will see the error --\> error: The ‘must’ expression should have a tailf:dependency. If is doesn’t, it will be checked for every commit.  
I am using confdversion=6.4.

And I perform confd compilation by this way --\>

confdc -c --annotate module1-ann.yang -o module1.fxs --verbose --fail-on-warnings -F module1.yang

I have tried doing this way --\>

tailf:annotate-module “module1”{  
tailf:annotate-statement grouping[name=‘grouping\_inside\_module1’]{  
tailf:annotate-statement leaf[name=‘leaf\_inside\_the\_above\_grouping’] {  
tailf:annotate-statement must"(…/leaf\_in\_a\_different\_grouping\_with\_type\_as\_leafref[key\_under\_different\_grouping=current()]/…/leaf\_needed\_to\_be\_compared=‘EXTERNAL’)" {  
tailf:dependency ‘…/leaf\_in\_a\_different\_grouping\_with\_type\_as\_leafref’;  
}  
}  
}  
}

I see this error --\>

bad argument value “must”(…/leaf\_in\_a\_different\_grouping\_with\_type\_as\_leafref[key\_under\_different\_grouping=current()]/…/leaf\_needed\_to\_be\_compared=‘EXTERNAL’)"": bad predicate

---

<div class="post-metadata">

### Author: ![per](https://avatars.discourse-cdn.com/v4/letter/p/9f8e36/32.png) [@per](https://dmap-community.ductus.global/u/per)
#### Post date: [March 3, 2020, 8:55pm UTC](https://dmap-community.ductus.global/t/using-must-condition-under-a-leaf-is-causing-internal-error/2940/16 "2020-03-03T20:55:31Z")

</div>

> [@arun\_kumar](#):
>
> I need a a tailf:dependency statement, otherwise I will see the error → error: The ‘must’ expression should have a tailf:dependency. If is doesn’t, it will be checked for every commit.

Agreed.

> [@arun\_kumar](#):
>
> confdc -c --annotate module1-ann.yang -o module1.fxs --verbose --fail-on-warnings -F module1.yang

That can’t possibly work, since `module1.yang` is taken as an argument to `-F`. When I try it in ConfD-6.4:

```auto
$ confdc -c --annotate module1-ann.yang -o module1.fxs --verbose --fail-on-warnings -F module1.yang
confdc: --compile needs a file to compile
        Try 'confdc -h' for help and more information

```

If I remove the `-F` option, it works fine. If you want to tell the compiler that no features should be supported, you need to follow the instruction in the confdc man page:

```auto
   -Ffeatures, --feature features
       Indicates that support for the YANG features should be present in
       the fxs file. features is a string on the form
       modulename:[feature(,feature)*]

```

I.e. to specify that none of the features in `module1` should be supported, you need to use

```auto
confdc -c --annotate module1-ann.yang -o module1.fxs --verbose --fail-on-warnings -F module1: module1.yang

```

which also works fine for me with ConfD-6.4.

> [@arun\_kumar](#):
>
> tailf:annotate-statement must"(…/leaf\_in\_a\_different\_grouping\_with\_type\_as\_leafref[key\_under\_different\_grouping=current()]/…/leaf\_needed\_to\_be\_compared=‘EXTERNAL’)" {

Don’t do that. In principle it is possible to give a predicate for the `must` annotation, but it has the same syntax as all the other predicates, no ‘"’ or ‘(’ but:

```auto
tailf:annotate-statement must[name='...the argument to must in the model...'] {

```

but getting the quoting right for `'...the argument to must in the model...'` is at best _really hard_, and often impossible due to limitations of XPath. There is absolutely no reason to try unless you have multiple `must` statements at the same “level” in the annotated module, and even then there is a simpler way to identify which of them you want to annotate.

---

<div class="post-metadata">

### Author: ![per](https://avatars.discourse-cdn.com/v4/letter/p/9f8e36/32.png) [@per](https://dmap-community.ductus.global/u/per)
#### Post date: [March 3, 2020, 10:00pm UTC](https://dmap-community.ductus.global/t/using-must-condition-under-a-leaf-is-causing-internal-error/2940/17 "2020-03-03T22:00:41Z")

</div>

Also, since what you had in that last `tailf:annotate-statement must` is nothing like what you showed for the actual `must` statement in the annotated module (more like what you had before the first correction that @mvf posted), it seems you keep changing things around and it is very difficult to understand what you actually have in your modules - and thus very difficult to help you.

I’ll post here what I actually have in the modules that compile fine for me in 6.4 - each module is preceded and followed by three “back-ticks” on a line of its own, to indicate pre-formatted text and thereby make the contents easy to read or copy, and I don’t _type_ any of the contents, just copy and paste exactly what is in the modules, to avoid mistakes. It is mostly based on your original post, with the corrections from @mvf applied. Perhaps you can do the same - or compare these modules with what you have.

module1.yang:

```auto
module module1 {
  namespace urn:module1;
  prefix m;

  grouping sample_grouping_1 {
    description "sample";
    leaf sample_leaf_1 {
      type leafref {
        path "../../../h1/h2_list/h2_key";
      }
      mandatory true;
    }
  }

  grouping sample_grouping_2 {
    uses sample_grouping_1;
    leaf sample_leaf_2 {
      type int32 {
        range "1..9600";
      }
      must 'deref(../sample_leaf_1)/../one_attribute_under_h2key = "EXTERNAL"';
      default 30;
    }
  }

  container h1 {
    list h2_list {
      key h2_key;
      leaf h2_key {
        type string;
      }
      leaf one_attribute_under_h2key {
        type string;
      }
    }
  }
  container h2 {
    container h3 {
      uses sample_grouping_2;
    }
  }
}

```

module1-ann.yang:

```auto
module module1-ann {
  namespace urn:module1-ann;
  prefix ma;

  import tailf-common {
    prefix tailf;
  }

  tailf:annotate-module "module1" {
    tailf:annotate-statement grouping[name='sample_grouping_2'] {
      tailf:annotate-statement leaf[name='sample_leaf_2'] {
        tailf:annotate-statement must {
          tailf:dependency '../sample_leaf_1';
          tailf:dependency '../../../h1/h2_list/one_attribute_under_h2key';
        }
      }
    }
  }
}

```

(I added another dependency in module1-ann - while the compiler will be happy with _any_ dependency, it is vitally important that the dependencies that you specify when the compiler can’t calculate them are _correct and complete_, and I don’t think that’s the case with the single dependency that you are trying to annotate.)
