Skip to content

lgi crashes with error "bad argument #1 to 'fromarray' (lgi.record expected, got table)" #358

@ji-cerny

Description

@ji-cerny

On Fedora 44 (beta), which includes lua 5.4.8, libffi 3.5.2, gobject-introspection 1.86.0, and lgi-0.9.2 (with some patches), lgi crashes with ffi.lua:86: bad argument #1 to 'fromarray' (lgi.record expected, got table). The current git master has the same problem, the test suite crashes with the same error.

To reproduce, it is sufficient to run the trivial lua script

local lgi = require("lgi")
local  Gtk = lgi.require("Gtk", "3.0")

It outputs

lua: /usr/share/lua/5.4/lgi/ffi.lua:87: bad argument #1 to 'fromarray' (lgi.record expected, got table)
stack traceback:
	[C]: in field 'fromarray'
	/usr/share/lua/5.4/lgi/ffi.lua:87: in function 'lgi.ffi.load_enum'
	/usr/share/lua/5.4/lgi/override/cairo.lua:55: in main chunk
	[C]: in function 'require'
	/usr/share/lua/5.4/lgi/namespace.lua:183: in function 'lgi.namespace.require'
	/usr/share/lua/5.4/lgi/namespace.lua:170: in function 'lgi.namespace.require'
	/usr/share/lua/5.4/lgi/namespace.lua:170: in function 'lgi.namespace.require'
	foo.lua:2: in main chunk
	[C]: in ?

It seems that that in ffi.load_enum function, enum_class.values is now a plain lua table and not an lgi.record. Claude AI proposed the following patch, which avoids the crash and make my scripts work, but for me it feels more like hiding the symptom than really solving the problem:

--- ffi.lua	2026-03-18 17:35:50.950336471 +0100
+++ ffi.lua.corrected	2026-03-18 15:03:16.377183180 +0100
@@ -83,10 +83,18 @@
    local type_class = GObject.TypeClass.ref(gtype)
    local enum_class = core.record.cast(
       type_class, is_flags and GObject.FlagsClass or GObject.EnumClass)
-   for i = 0, enum_class.n_values - 1 do
-      local val = core.record.fromarray(enum_class.values, i)
-      enum_component[core.upcase(val.value_nick):gsub('%-', '_')] = val.value
-   end
+      for i = 0, enum_class.n_values - 1 do
+	      -- Check if values is already a table (new GI) or needs fromarray (old GI)
+	      local val
+	      if type(enum_class.values) == 'table' and getmetatable(enum_class.values) == nil then
+		      -- New GI format: values is a plain Lua table, access directly
+		      val = enum_class.values[i+1]
+	      else
+		      -- Old GI format: values is an lgi.record array
+		      val = core.record.fromarray(enum_class.values, i)
+	      end
+	      enum_component[core.upcase(val.value_nick):gsub('%-', '_')] = val.value
+      end
    type_class:unref()
    return enum_component
 end

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions