diff --git a/rsc/lua/module.lua b/rsc/lua/module.lua
index 8e240778c4609305e045aab43328507f5f8d05f2..52c2875163968d24e9286f1494c833cd2266d8d0 100644
--- a/rsc/lua/module.lua
+++ b/rsc/lua/module.lua
@@ -2,14 +2,6 @@
     Utilities to handle the module declaration files.
 ]]
 
--- Local private function: try to import options from a table into a job or a
--- module declaration.
-function ___tryImportOptions(thing, tbl)
-    if tbl["options"] and type(tbl.options) == "table" then
-        thing:setOptions(tbl.options)
-    end
-end
-
 -- Check if the type of the argument is 'table'
 function ___checkTable(tbl)
     if type(tbl) ~= "table" then
@@ -17,6 +9,16 @@ function ___checkTable(tbl)
     end
 end
 
+-- Local private function: try to import options from a table into a job or a
+-- module declaration.
+function ___tryImportOptions(thing, tbl)
+    ___checkTable(tbl)
+    if tbl["options"] then
+        ___checkTable(tbl.options)
+        thing:setOptions(tbl.options)
+    end
+end
+
 -- The option declaration block:
 --      DeclareOption { opt1 = val1, opt2 = val2 }
 function DeclareOption(opt)
@@ -105,11 +107,12 @@ function DeclareModule(tbl)
     if tbl.description then module:setDescription(tbl.description) end
     if tbl.revision    then module:setRevision(tbl.revision) end
     if tbl.imports     then module:setImports(tbl.imports) end
-    ___tryImportOptions(module, tbl)
 
     -- A little more complicated thing
-    if tbl.functions then module:setFunctions(tbl.functions) end
     if tbl.jobs      then module:setJobs(tbl.jobs) end
+    if tbl.functions then module:setFunctions(tbl.functions) end
+
+    ___tryImportOptions(module, tbl)
 
     -- Register the module!
     module:pushToRuntime()
diff --git a/src/Lib/Script/CRTPLuaScriptObject.cc b/src/Lib/Script/CRTPLuaScriptObject.cc
index e696188627369f59c5b675386d482ffb2063434d..21e83d1e1f8e666026a79b4e51a9e6a880a2b5d3 100644
--- a/src/Lib/Script/CRTPLuaScriptObject.cc
+++ b/src/Lib/Script/CRTPLuaScriptObject.cc
@@ -10,8 +10,7 @@ FreeFunctions::print(lua_State *L) noexcept
 {
     const std::string_view arg = CHECK_STRING_VIEW(L, 1);
     out(LuaContext::getContext(L)) << "OUT: " << arg << "\n";
-    lua_settop(L, 0);
-    return 0;
+    LUA_RETURN_NOTHING(L);
 }
 
 // ModuleDeclaration
@@ -22,8 +21,7 @@ ModuleDeclaration::setName(lua_State *const L) noexcept
     auto *const self = ModuleDeclaration::CHECK(L, 1);
     self->moduleName = CHECK_STRING_VIEW(L, 2);
     Utils::trim(self->moduleName);
-    lua_settop(L, 0);
-    return 0;
+    LUA_RETURN_NOTHING(L);
 }
 
 int
@@ -32,8 +30,7 @@ ModuleDeclaration::setAuthorName(lua_State *const L) noexcept
     auto *const self = ModuleDeclaration::CHECK(L, 1);
     self->authorName = CHECK_STRING_VIEW(L, 2);
     Utils::trim(self->authorName);
-    lua_settop(L, 0);
-    return 0;
+    LUA_RETURN_NOTHING(L);
 }
 
 int
@@ -42,8 +39,7 @@ ModuleDeclaration::setRevision(lua_State *const L) noexcept
     auto *const self = ModuleDeclaration::CHECK(L, 1);
     self->revision   = CHECK_STRING_VIEW(L, 2);
     Utils::trim(self->revision);
-    lua_settop(L, 0);
-    return 0;
+    LUA_RETURN_NOTHING(L);
 }
 
 int
@@ -52,8 +48,7 @@ ModuleDeclaration::setDescription(lua_State *const L) noexcept
     auto *const self        = ModuleDeclaration::CHECK(L, 1);
     self->moduleDescription = CHECK_STRING_VIEW(L, 2);
     Utils::trim(self->moduleDescription);
-    lua_settop(L, 0);
-    return 0;
+    LUA_RETURN_NOTHING(L);
 }
 
 int
@@ -62,8 +57,7 @@ ModuleDeclaration::setImplementationFile(lua_State *const L) noexcept
     auto *const self         = ModuleDeclaration::CHECK(L, 1);
     self->implementationFile = CHECK_STRING_VIEW(L, 2);
     Utils::trim(self->implementationFile);
-    lua_settop(L, 0);
-    return 0;
+    LUA_RETURN_NOTHING(L);
 }
 
 int
@@ -78,50 +72,56 @@ ModuleDeclaration::setImports(lua_State *const L) noexcept
         err(context) << "Add import " << import << " for module " << self->moduleName << "\n";
         return false; // Value was not popped from stack!
     });
-    lua_settop(L, 0);
-    return 0;
+    err(context) << "Imports done!\n";
+    LUA_RETURN_NOTHING(L);
 }
 
 int
 ModuleDeclaration::setOptions(lua_State *const L) noexcept
 {
-    auto *const self = ModuleDeclaration::CHECK(L, 1);
-    IterateOverArray(L, 2, [self, L]() noexcept -> bool {
+    auto *const self    = ModuleDeclaration::CHECK(L, 1);
+    auto *const context = LuaContext::getContext(L);
+    IterateOverArray(L, 2, [&context, self, L]() noexcept -> bool {
         OptionDeclaration *const opt = OptionDeclaration::CHECK(L, -1);
         self->moduleOptions.emplace_back(opt);
-        lua_setuservalue(L, 1); // Tie the opt to the module
-        return true;            // The value was popped from the stack
+        err(context) << "Add option for module " << self->moduleName << "\n";
+        self->addUserValue(L, 1); // Tie the opt to the module
+        return true;              // The value was popped from the stack
     });
-    lua_settop(L, 0);
-    return 0;
+    err(context) << "Options done!\n";
+    LUA_RETURN_NOTHING(L);
 }
 
 int
 ModuleDeclaration::setFunctions(lua_State *const L) noexcept
 {
-    auto *const self = ModuleDeclaration::CHECK(L, 1);
-    IterateOverArray(L, 2, [self, L]() noexcept -> bool {
+    auto *const self    = ModuleDeclaration::CHECK(L, 1);
+    auto *const context = LuaContext::getContext(L);
+    IterateOverArray(L, 2, [&context, self, L]() noexcept -> bool {
         FunctionDeclaration *const fun = FunctionDeclaration::CHECK(L, -1);
         self->moduleFunctions.emplace_back(fun);
-        lua_setuservalue(L, 1); // Tie the function to the module
-        return true;            // The value was popped from the stack
+        err(context) << "Add function " << fun->name << " to module " << self->moduleName << "\n";
+        self->addUserValue(L, 1); // Tie the function to the module
+        return true;              // The value was popped from the stack
     });
-    lua_settop(L, 0);
-    return 0;
+    err(context) << "Functions done!\n";
+    LUA_RETURN_NOTHING(L);
 }
 
 int
 ModuleDeclaration::setJobs(lua_State *const L) noexcept
 {
-    auto *const self = ModuleDeclaration::CHECK(L, 1);
-    IterateOverArray(L, 2, [self, L]() noexcept -> bool {
+    auto *const self    = ModuleDeclaration::CHECK(L, 1);
+    auto *const context = LuaContext::getContext(L);
+    IterateOverArray(L, 2, [&context, self, L]() noexcept -> bool {
         JobDeclaration *const job = JobDeclaration::CHECK(L, -1);
         self->moduleJobs.emplace_back(job);
-        lua_setuservalue(L, 1); // Tie the job to the module
-        return true;            // The value was popped from the stack
+        err(context) << "Add job " << job->name << " to module " << self->moduleName << "\n";
+        self->addUserValue(L, 1); // Tie the job to the module
+        return true;              // The value was popped from the stack
     });
-    lua_settop(L, 0);
-    return 0;
+    err(context) << "Jobs done!\n";
+    LUA_RETURN_NOTHING(L);
 }
 
 int
@@ -130,8 +130,9 @@ ModuleDeclaration::pushToRuntime(lua_State *const L) noexcept
     ModuleDeclaration *const self = CHECK(L, 1);
     auto *const context           = LuaContext::getContext(L);
     err(context) << "Register module \"" << self->moduleName << "\" in the runtime!\n";
+    lua_settop(L, 1);
     context->registerModuleDeclaration(self);
-    return 0;
+    LUA_RETURN_NOTHING(L);
 }
 
 // OptionDeclaration
@@ -177,8 +178,7 @@ OptionDeclaration::addOptionContent(lua_State *const L) noexcept
     else
         luaL_error(L, "Unsupported type %s", luaL_typename(L, 3));
 
-    lua_settop(L, 0);
-    return 0;
+    LUA_RETURN_NOTHING(L);
 }
 
 // JobDeclaration
@@ -207,8 +207,7 @@ int
 JobDeclaration::setName(lua_State *L) noexcept
 {
     JobDeclaration::CHECK(L, 1)->name = CHECK_STRING_VIEW(L, 2);
-    lua_settop(L, 0);
-    return 0;
+    LUA_RETURN_NOTHING(L);
 }
 
 int
@@ -227,20 +226,18 @@ JobDeclaration::setOptions(lua_State *L) noexcept
         }
 
         job->options.push_back(opt);
-        lua_setuservalue(L, 1); // Tie T[i] to job and pop stack
-        return true;            // Value was popped from the stack
+        job->addUserValue(L, 1); // Tie T[i] to job and pop stack
+        return true;             // Value was popped from the stack
     });
 
-    lua_settop(L, 0);
-    return 0;
+    LUA_RETURN_NOTHING(L);
 }
 
 int
 JobDeclaration::setImportFromScript(lua_State *L) noexcept
 {
     JobDeclaration::CHECK(L, 1)->parentScript = CHECK_STRING_VIEW(L, 2);
-    lua_settop(L, 0);
-    return 0;
+    LUA_RETURN_NOTHING(L);
 }
 
 // FunctionDeclaration
@@ -261,14 +258,12 @@ int
 FunctionDeclaration::setName(lua_State *L) noexcept
 {
     FunctionDeclaration::CHECK(L, 1)->name = CHECK_STRING_VIEW(L, 2);
-    lua_settop(L, 0);
-    return 0;
+    LUA_RETURN_NOTHING(L);
 }
 
 int
 FunctionDeclaration::setImportFromScript(lua_State *L) noexcept
 {
     FunctionDeclaration::CHECK(L, 1)->parentScript = CHECK_STRING_VIEW(L, 2);
-    lua_settop(L, 0);
-    return 0;
+    LUA_RETURN_NOTHING(L);
 }
diff --git a/src/Lib/Script/CRTPLuaScriptObject.hh b/src/Lib/Script/CRTPLuaScriptObject.hh
index a1043d6b9b3f4c7e32ee13db077618ad100ec851..f255335cb942c69a6a2f91394e1ba23dd55f0af3 100644
--- a/src/Lib/Script/CRTPLuaScriptObject.hh
+++ b/src/Lib/Script/CRTPLuaScriptObject.hh
@@ -13,6 +13,7 @@ namespace Vivy::Script
 #define LUA_DECL_METHOD(class, name)            luaL_Reg{ #name, class ::name   }
 #define LUA_DECL_META_METHOD(class, meta, name) luaL_Reg{ meta,  class ::name   }
 #define LUA_DECL_CREATE(class)                  luaL_Reg{ "new", class ::CREATE }
+#define LUA_RETURN_NOTHING(L)                   { lua_settop(L, 0); return 0; }
 // clang-format on
 
 #define script_class(theClassName) \
@@ -44,21 +45,18 @@ protected:
 
         const int countInt = static_cast<const int>(count);
         for (int i = 1; i <= countInt; ++i) {
+            luaL_checktype(L, tblIndex, LUA_TTABLE);
             lua_pushinteger(L, i);     // i -> top stack
-            lua_gettable(L, tblIndex); // T[i] -> top stack
+            lua_gettable(L, tblIndex); // T[i] -> top stack and pop i
 
-            // Sentinel check
             if (lua_type(L, -1) == LUA_TNIL)
-                break;
+                break; // Sentinel check
 
             // If the callback didn't pop the object form the stack, pop
             // it ourself. The value will be accessible at the top of the
             // stack (index -1).
             if (!callback())
                 lua_pop(L, -1);
-
-            // Pop i from the stack
-            lua_pop(L, -1);
         }
     }
 
@@ -98,12 +96,12 @@ protected:
     static inline constexpr luaL_Reg luaRegDefaultTOSTRING = { "__tostring", TOSTRING };
 
 public:
-    static Object *CHECK(lua_State *L, int index) noexcept
+    static Object *CHECK(lua_State *const L, const int index) noexcept
     {
         return reinterpret_cast<Object *>(luaL_checkudata(L, index, Object::className));
     }
 
-    static void Register(lua_State *L) noexcept
+    static void Register(lua_State *const L) noexcept
     {
         // Fill the method table, newclass = {}
         lua_newtable(L);
@@ -142,6 +140,18 @@ public:
         lua_pop(L, 1);                              // drop method-table
         lua_register(L, Object::className, CREATE); // Register the create method
     }
+
+private:
+    // The user value count
+    int userValueCount{ 0 };
+
+protected:
+    // Add a user value to this object. Do not used lua_setuservalue or
+    // lua_setiuservalue directly, use this proxy method.
+    void addUserValue(lua_State *const L, const int index) noexcept
+    {
+        lua_setiuservalue(L, index, ++userValueCount);
+    }
 };
 
 // Option declaration
diff --git a/src/Lib/Script/LuaContext.cc b/src/Lib/Script/LuaContext.cc
index 9585956ac6e3f73ca46ab738d80d2c1bfdddb3c0..554d104d19aab53c3c2504cdc6dd9a7d18572118 100644
--- a/src/Lib/Script/LuaContext.cc
+++ b/src/Lib/Script/LuaContext.cc
@@ -125,7 +125,10 @@ LuaContext::registerModuleDeclaration(const ModuleDeclaration *const mod) noexce
         return Code::Error;
     }
 
-    int r = luaL_ref(L, LUA_REGISTRYINDEX);
+    streamErr << "Try to register module \"" << mod->moduleName << "\"\n";
+
+    ModuleDeclaration::CHECK(L, -1);
+    const int r = luaL_ref(L, LUA_REGISTRYINDEX);
     modules.emplace(mod->moduleName, r);
     return Code::Success;
 }
@@ -135,6 +138,7 @@ LuaContext::getModule(const std::string_view name) const noexcept
 {
     if (modules.count(name) >= 1) {
         const int r = modules.at(name);
+        streamErr << "Try to get module \"" << name << "\" with register key " << r << "\n";
         lua_rawgeti(L, LUA_REGISTRYINDEX, r);
         return ModuleDeclaration::CHECK(L, -1);
     } else {
diff --git a/utils/lua/sample-spec.module b/utils/lua/sample-spec.module
index cdca8c8720386e2fb8fe7c32c179595452fb89d9..a6886f8da78209663e01fa5cd62297b6d9bd57e1 100644
--- a/utils/lua/sample-spec.module
+++ b/utils/lua/sample-spec.module
@@ -11,12 +11,6 @@ fun1 = DeclareFunction { "tripleCopySyl" }
 fun2 = DeclareFunction { "printFoo" }
 fun3 = ImportFunction  { "utils", "prettyPrint" }
 
-print(tostring(custom_opt))
-print(tostring(job3))
-print(tostring(job2))
-print(tostring(fun3))
-print(tostring(fun2))
-
 DeclareModule {
     name        = "sample-spec",
     description = "Sample script used for the specification proposition",