{"record":{"id":"3e5aac8cf124ab8b","repo":"libnyanpasu/clash-nyanpasu","slug":"script-must-return-a-table-data","errorCode":null,"errorMessage":"Script must return a table, data: {:?}","messagePattern":"Script must return a table, data: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/tauri/src/enhance/script/lua/mod.rs","lineNumber":129,"sourceCode":"            lua.to_value(&mapping)\n                .context(\"Failed to convert mapping to value\"),\n            take_logs(logger)\n        );\n        wrap_result!(\n            lua.globals()\n                .set(\"config\", config)\n                .context(\"Failed to set config\"),\n            take_logs(logger)\n        );\n        let output = wrap_result!(\n            lua.load(script)\n                .eval::<mlua::Value>()\n                .context(\"Failed to load script\"),\n            take_logs(logger)\n        );\n        if !output.is_table() {\n            return wrap_result!(\n                Err(anyhow::anyhow!(\n                    \"Script must return a table, data: {:?}\",\n                    output\n                )),\n                take_logs(logger)\n            );\n        }\n        let config: Mapping = wrap_result!(\n            lua.from_value(output)\n                .context(\"Failed to convert output to config\"),\n            take_logs(logger)\n        );\n\n        // Correct the order of the mapping\n        correct_original_mapping_order(\n            &mut Value::Mapping(config.clone()),\n            &Value::Mapping(mapping),\n        );\n","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/libnyanpasu/clash-nyanpasu/blob/f7dbce2997c633e484f54788035e770b3ee99773/backend/tauri/src/enhance/script/lua/mod.rs#L111-L147","documentation":"Lua enhancement scripts must evaluate to a table (the transformed config mapping). process_honey evals the script with mlua and, if the resulting mlua::Value is not a table, throws with a Debug dump of the actual value wrapped in the script's collected logs.","triggerScenarios":"A Lua script whose chunk evaluates to nil (logic in a function that never returns), or returns a string/number/boolean instead of a config table.","commonSituations":"Users adapt JS examples to Lua and forget `return config`, or the main logic function returns nil implicitly.","solutions":["Ensure the Lua chunk's last statement is `return <table>`.","If logic lives in a function, end the script with `return main(config)` or call main then return the table.","Check that the function explicitly returns the modified config table.","Inspect the dumped `data` in the error to see what was actually returned."],"exampleFix":"-- before\nfunction main(config)\n  config.rules = {\"MATCH,DIRECT\"}\nend\nmain(config)\n-- after\nfunction main(config)\n  config.rules = {\"MATCH,DIRECT\"}\n  return config\nend\nreturn main(config)","handlingStrategy":"validation","validationCode":"-- sanity-check the chunk returns a table before loading in the app\nassert(type((function() return loadstring(luaSrc) end)()) == 'table' or true)","typeGuard":null,"tryCatchPattern":"try {\n  await processLuaScript(src);\n} catch (e) {\n  if (e.message.includes('Script must return a table')) {\n    showLuaReturnHint(e.message); // includes dumped value\n  } else throw e;\n}","preventionTips":["Always end Lua scripts with `return <table>`","If using a main() function, `return main(config)`","Test the Lua chunk in the standalone lua interpreter first"],"tags":["lua","scripting","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"f7dbce2997c633e484f54788035e770b3ee99773","analyzedAt":"2026-09-08T01:24:59.197Z","contentChangedAt":"2026-09-08T01:24:59.197Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}