Consider the following code which uses \keys_set_known:nnN:


\keys_define:nn {empty_module} {}
\keys_define:nn {module1}
   {key1 .code:n = {\keys_set:nn {empty_module} {a_key}}}
\keys_set_known:nnN {module1} {key1} \l_tmpa_clist
\clist_show:N \l_tmpa_clist


When executing \keys_set_known:nnN {module1} {key1} \l_tmpa_clist, the key key1 is found in module1 and, then, the corresponding code \keys_set:nn {empty_module} {a_key} is executed. However, there is no key a_key in empty_module and I would expect an error. But, instead, the key a_key is transferred to \l_tmpa_clist as we can see with the clist_show:N.

I would like to know whether this is a bug or the expected behaviour as suggested (maybe) by interface3.pdf:

Use of \keys_set_known:nnN can be nested, with the correct residual keyval list returned at each stage.


2 Answers 2


I'm not sure if this can be called expected behaviour, but it's how the function is implemented.

From expl3-code.tex, the definition of \keys_set_known:nnN is (plus wrapper code and a few more things):

\keys_set_known:nn {#2} {#3}
\tl_set:Nx #4 { \exp_not:o { \l__keys_unused_clist } }

where #2 is the module, #3 is the key-value list, and #4 is the tl var to store the unused keys. The function is the same as \keys_set_known:nn but it saves the contents of \l__keys_unused_clist in #4. So let's go for \keys_set_known:nn.

The code for \keys_set_known:nn now does:

\bool_set_true:N \l__keys_only_known_bool
\keys_set:nn {#1} {#2}
\bool_set_false:N \l__keys_only_known_bool

which is basically \keys_set:nn with a different behaviour for unknown keys.

(somewhere in the code of l3keys you can see:

\bool_if:NTF \l__keys_only_known_bool
  { \__keys_store_unused: }
      { \c__keys_inherit_root_tl \__keys_parent:o \l_keys_path_tl }
      { \__keys_execute_inherit: }
      { \__keys_execute_unknown: }

which either stores the unknown key in \l__keys_unused_clist or tries to do another thing with the key, depending of the value of \l__keys_only_known_bool).

So, the bottom-line is: when you call \keys_set_known:nnN you temporarily disable the unknown key-checking code, so the error you expected to see doesn't appear. Instead, as an unknown key is found, the \__keys_store_unused: is called for a_key and it is stored in the unused list at the end.


This is now fixed in the development code: see https://github.com/latex3/latex3/issues/526. The next release will take place within a few days and will address this and other l3keys issues.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .