Log: There is no context to infer the closure's argument types from

I get these messages in the log openhab.log at start up and when changing these rule files:

2018-05-18 07:08:32.976 [INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'main.rules', using it anyway:
There is no context to infer the closure's argument types from. Consider typing the arguments or put the closures into a typed context.
2018-05-18 07:08:32.988 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'main.rules'

VSCode is not suggesting anything wrong.

It is only in rules where I use members.filter or allMembers.filter


rule "Battery Monitor"
    Time cron "0 55 10 * * ?"
    if (!Batteries.allMembers.filter( [ battery | (battery.state as Number) <= (lowBatteryThreshold) ] ).empty) {
        val report = Batteries.allMembers.filter( [ (state as Number) <= (lowBatteryThreshold) ] ).sortBy( [ state as DecimalType ] ).map[ name + ": " + state.format("%d%%") ].join("\n")
        val message = "Battery levels:\n\n" + report + "\n\nRegards,\n\nOur House"
        sendMail("vzorglub@gmail.com", "Low battery alert !", message)


rule "Generic Windows Changed"
    Member of HeatingWindows changed or
    Member of Radiators changed
    val room = triggeringItem.name.split("_").get(0)
    val window = Windows.members.filter[ i | i.name.contains(room) ].head
    val radiator = Radiators.members.filter [ i | i.name.contains(room) ].head
    if (radiator.state == ON) {
        if (window.state == OPEN) {
            sendCommand(room + "_RadiatorValve", "OFF")
    if (radiator.state == OFF) {
        if (window.state == CLOSED) {
            val offset = House_HeatingOffset.state as Number
            val target = Targets.members.filter[ i | i.name.contains(room) ].head.state as Number
            val ambient = AmbientTemps.members.filter[ i | i.name.contains(room) ].head.state as Number
            if (ambient <= (target - (offset / 2))) {
                sendCommand(room + "_RadiatorValve", "ON")

Anything to suggest?

In my opinion this is based on the fact that the system has ti guess which kind of type is returned. Try somsthing like

val ContactItem window = Windows.members.filter[ i | i.name.contains(room) ].head as ContactItem
1 Like

Thomas is right, at compile time (i.e. when the Rules are loaded) the Rules Engine can’t figure out what type is being used in the lambdas (everything between [ ] is a lambda). In particular, it can’t figure out what the type of battery is in the first filter in your first Rule or i isin the Windows filter in your second rule.

Adding the type to the result of head might work. If it doesn’t give a type to the items in the filter.

    val window = Windows.members.filter[ ContactItem i | i.name.contains(room) ].head

I just did a grep through my Rules and I’ve see I use both over the years.


I had this come up because I used a not yet defined group name in a lambda. After I defined the group in the .items file, everything was OK


I’m trying to figure this syntax out and came across this posting . . .

This syntax works but I think the error I’m getting on a clean boot up is tied to this syntax.

if (Temperatures.members.filter(s | s.state > 89).size > 0) {             // check for any temperature sensors in the house that are very high

I tried to re-write it based on the posting but it fails; any suggestions on how it should be written?

val SensorItem firesensor = Temperatures.members.filter[s | s.state].size as SensorItem 

if (firesensor.state > 89) {             // check for any temperature sensors in the house that are very high

Best, Jay

I never managed to get rid of them
It’s only a warning and the rules run

What’s a SensorItem? As far as I know there is no such Item type. Is it a Number Item or a Number:Temperature Item?

And .size returns the number of entries in what the filter returns. It’s just an int, not even a Number. You can’t cast an int to SensorItem even if there were such a thing as a Sensor Item.

The “closure” part is the [ ] after the filter. The error is saying that it can’t figure out what type s is. We know that s is an Item so use filter[ GenericItem s | s.state != NULL && s.state != UNDEF && s.state > 89 ].size. Note, I added a bunch of other tests to avoid an error should any member of Temperatures be NULL or UNDEF.


Thanks Rich for helping me out!

I just made up the value SensorItem; wasn’t sure what/where this variable came from. All the items that report temperatures are NUMBERS.

Example below:

Number 	 FurnaceSensor_Temp 			"Floor Temperature [%.2f]" 							(FurnaceWater, Temperatures)	{ channel="zwave:device:ffffffd1ffffffb2ffffffdbffffffad:node13:sensor_temperature" }

Based on that; I’m assuming your syntax will still work? Here’s what I’m proposing to use:

if (Temperatures.members.filter[ GenericItem s | s.state != NULL && s.state != UNDEF && s.state > 89 ].size > 0)

Best, Jay

Hi Vincent, did you get this to work? I too get the error.

my rule is:

al Number lowBatteryThreshold = 35

rule "Battery Status Check"
    Item gBatteries changed
    var String msg = ""
    var triggertDevices = gBatteries.members.filter[s|s.state <= 35]

    triggertDevices.forEach [ i |
        msg = msg + (transform("MAP", "batteries.map", i.name) + ': ' + i.state.toString) + '%\n'
        logInfo("Battery Check","Low battery at " + i.name + ": " + i.state.toString + "%")

    if (msg != "") {
     sendBroadcastNotification(msg + " of your battery remaining")

No, not really.
I use jython now

No worries