What does the error "Internal error: Lambda has non-function type blocked-156306" mean?


While I have tried to ensure the logic within the discover() function is sound, I am concerned that I might be missing a fundamental constraint of the Type Function API that triggers this *blocked* state.

Could someone please review the recursive structure below and explain what this internal error indicates?

Heres the full code for reference:

--!strict

type IndexAndValue = {Index:any,Value:any}

export type FlattedTable = {
	Tables:{
		[string]:{[string]:IndexAndValue}
	},
	Id:string
}

type function GetFlattedTableType(unflattedTable:type)
	
	local s = types.singleton
	
	local tables = types.newtable()
	
	local id = tostring(unflattedTable)
	
	local function discover(t:type):type?
		
		if not t:is("table") then
			return nil
		end
		
		local tableId = tostring(t)
		
		local infoTableAlreadyExists = tables:readproperty(s(tableId))
		
		if infoTableAlreadyExists then
			return infoTableAlreadyExists
		end
		
		local infoTable = types.newtable()
		
		local infoTable_LEN = 0
		
		tables:setproperty(s(tableId),infoTable)
		
		for index, readAndWrite in t:properties() do
			
			local value = t:readproperty(index)
			
			-- type checker do not understand it btw (fix it roblox!!!!)
			if value == nil then
				continue
			end
			
			if index:is("table") then
				local convertedIndex = discover(index)
				
				if convertedIndex then
					index = convertedIndex
				end
			end 

			if value:is("table") then
				local convertedValue = discover(value)
				
				if convertedValue then
					value = convertedValue
				end
			end
			
			local indexAndValue = types.newtable{
				[s("Index")] = index,
				[s("Value")] = value
			}

			infoTable:setproperty(s(tostring(infoTable_LEN + 1)),indexAndValue)
			infoTable_LEN += 1
			
		end
		
		
		return types.newtable{ [s("Id")] = s(tableId) }
		
	end
	
	discover(unflattedTable)
	
	return types.newtable{
		[s("Tables")] = tables,
		[s("Id")] = s(id),
	}
	
end

--type function GetUnflattedTableType(flattedTable)
	
--end

local TableFlattener = {}

function TableFlattener.Encode<T>(tbl:T):GetFlattedTableType<T>
	
	local tables = {}
	
	local id = tostring(tbl)
	
	local function discover(t)
		
		if typeof(t) ~= "table" then
			return
		end
		
		local tableId = tostring(t)
		
		local infoTableAlreadyExists = tables[tableId]
		
		if infoTableAlreadyExists then
			return infoTableAlreadyExists
		end
		
		local infoTable = {}
		
		local infoTable_LEN = 0
		
		tables[tableId] = infoTable
		
		for index, value in pairs(t) do
			
			if typeof(index) == "table" then
				index = discover(index)
			end
			if typeof(value) == "table" then
				value = discover(value)
			end
			
			local indexAndValue = {
				Index = index,
				Value = value,
			}
			
			infoTable[tostring(infoTable_LEN + 1)] = indexAndValue
			infoTable_LEN += 1
			
		end
		
		return {Id = tostring(t)}
		
	end
	
	discover(tbl)
	
	return {
		Tables = tables,
		Id = id
	}
	
end

--function TableFlattener.Decode(flattedTable)
	
--end

return TableFlattener

That’s a C++ error from within Luau itself. It’s already been reported as an issue on the Luau GitHub, so it should get fixed eventually (it’s a bug).

1 Like

It’s actually a limitation of the Luau solver. It happens when you use a type function with generic arguments as the return type of a generic function. basically this case:

type function F(t: type): type
    return t
end

local function f<T>(p: T): F<T> -- Type Error: Internal error: Lambda has non-function type *blocked-62021*
    return {}
end

That error means that, for some reason, the solver couldn’t infer a concrete type. This can happen in different situations, but in this case it’s just a limitation of the solver itself.

You can defer the type function inference, for example by wrapping it in a table

local function f<T>(p: T): {F<T> }
    return {}
end

But the most effective approach is to make the solver stop trying to infer the return value by using a type cast

local function f<T>(p: T): F<T>
    return {} :: F<T>
end

In your case, it would be something like this.

    return {
        Tables = tables,
        Id = id
    } :: GetFlattedTableType<T>

Just a heads-up, there are a few other issues in your code, but that’s a different topic.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.