Problem with JavaScript rule with SystemStartLevel not loading

  • Platform information:
    • Hardware: Raspberry Pi 4
    • OS: CENTOS 9
    • Java Runtime Environment: OpenJDK version “21.0.10” 2026-01-20 LTS
    • openHAB version: 5.1.3
  • Issue of the topic: A text-based rule with the SystemStartlevelTrigger(100) doesn’t load when OH restarts, when the file is modified, or when it is manually triggered with an item change

I have the following rule:

rules.JSRule({
    name: "Initialize Items",
    description: "Initialize items on system startup",
    triggers: [triggers.SystemStartlevelTrigger(100),
        triggers.ItemCommandTrigger('Override_InitializeItems','ON')
    ],
    execute: () => {
        console.debug("System Actions> Initialize Items> Starting.");

        console.debug("System Actions> Initialize Items> Initializing scenes.");
        items.LR_Scene_Automated.sendCommand(ON);
        items.MBR_Scene_Automated.sendCommand(ON);
        items.NBR_Scene_Automated.sendCommand(ON);
        items.LR_Scene_Movie.sendCommand(OFF)
        ...

Somehow, it doesn’t get triggered when the system reaches level 100 (as you can see in the logs below). I have set the level to 80, but it still doesn’t work. The log level of the file where the rule is located is set to DEBUG, but not even the first line gets printed.

I have also tried it without the item command

triggers: [triggers.SystemStartlevelTrigger(100)
        ],

I can see in the logs that the file gets loaded. I modified it after the system reached level 100, seeing that

14:11:33.962	INFO	
org.openhab.core.automation.module.script.rulesupport.loader.AbstractScriptFileWatcher
(Re-)Loading script '/etc/openhab/automation/js/System.js'
info_circle 14:11:34.705	INFO	
org.openhab.automation.jsscripting.file.System.js
{}
info_circle 14:11:34.715	INFO	
org.openhab.automation.openhab-js.rules
Adding rule: Telegram ask internal handler
info_circle 14:11:34.735	INFO	
org.openhab.automation.openhab-js.rules
Adding rule: Telegram commands handler
info_circle 14:11:34.763	INFO	
org.openhab.automation.jsscripting.openhab-js.rules
Adding rule: Initialize Items
info_circle 14:11:34.782	INFO	
org.openhab.automation.jsscripting.openhab-js.rules
Adding rule: Report Offline Thing
info_circle 14:11:34.792	INFO	
org.openhab.core.automation.module.script.rulesupport.loader.AbstractScriptFileWatcher
(Re-)Loading script '/etc/openhab/automation/js/Time_Machine.js'
info_circle 14:11:35.863	INFO	
org.openhab.automation.jsscripting.openhab-js.rules
Adding rule: Calculate Time Of Day
info_circle 14:11:35.884	INFO	
org.openhab.automation.jsscripting.openhab-js.rules
Adding rule: Recalculate Time Of Day
info_circle 14:11:42.144	INFO	
openhab.event.StartlevelEvent
Startlevel '80' reached.
info_circle 14:11:42.149	INFO	
openhab.event.StartlevelEvent
Startlevel '100' reached.
(Re-)Loading script '/etc/openhab/automation/js/System.js'
info_circle 14:14:47.437	INFO	
org.openhab.automation.jsscripting.file.System.js
{}
info_circle 14:14:47.468	INFO	
org.openhab.automation.openhab-js.rules
Adding rule: Telegram ask internal handler
info_circle 14:14:47.498	INFO	
org.openhab.automation.openhab-js.rules
Adding rule: Telegram commands handler
info_circle 14:14:47.521	INFO	
org.openhab.automation.jsscripting.openhab-js.rules
Adding rule: Initialize Items
info_circle 14:14:47.539	INFO	
org.openhab.automation.jsscripting.openhab-js.rules
Adding rule: Report Offline Thing

When I try to trigger it with the item command, I see the command in the logs, but still the rule doesn’t get triggered.

It’s the only rule I have with the SystemStartlevelTrigger trigger.

I found SystemStartlevelTrigger not firing and SystemStartlevelTrigger in javascript, but they didn’t help.

Any suggestions?

Are you sure the rule doesn’t get triggered? Your log statements are at the DEBUG level and there’s no way for us to tell if you’ve enabled debug level logging to see those log statements.

In addition to debug level logging for at least that rule, you can also enable INFO level logging on openhab.event.RuleStatusInfoEvent. This will add a log to events.log when a rule starts running and when it stops.

You can also manually run the rule from MainUI. Does it run then?

From the item states I am sure. The purpose of the rule is to initialize many items (that should not be persisted) to their default start values. Since I migrated to JavaScript at the end of last year, I haven’t ever seen the rule working, and all items remain uninitialized. I have to manually initialize them through the UI.

What surprises me the most is that the item command trigger doesn’t work, even though other rules with item and group item commands work well. As you can also see, the rule has no conditionals at the beginning, so at the most basic, it should print the info to the console and send the commands to the items.

I will do what you suggested and check.

I don’t use the JSRule builder at all, so I don’t know if command types are injected into the rule context, but if not then ON and OFF are undefined and sendCommand(undefined) is not what you want. Try items.LR_Scene_Automated.sendCommand("ON");

I use these declarations:

const { items, triggers, things } = require('openhab')
var { ON, OFF} = require('@runtime');

According to the code, Item.sendCommand accepts:

| string | number | ZonedDateTime | Instant | Quantity | HostState | null | |
|:—|:—|

ON and OFF are OnOffType which is none of these. Though following the code it looks like anything that is not one of the above gets converted to a String anyway, so passing OnOffTypes is probably not the problem, even it it’s not really technically supported. But I would be cautious as there might be a change in the future that could break this and since it’s not a documented feature it wouldn’t be considered a breaking change. I doubt there is a planned change but it’s hard to predict the future.

The key diagnositc here though is to distinguish whether the rule truely isn’t triggering, the rule is triggering and not running the action, or the action is failing silently in some way. That’s why we need you to:

  1. change the logging statement to console.info or setting the rule’s logging level to debug (be default debug level logging is not outputed.
  2. change the logging level for RuleStatusInfoEvent so we see when the rule is triggering independently of the code the rule runs
  3. manually running the rule to see if it behaves differently when manually invoked instead of triggered through an event.

They are not. And there really isn’t much reason to as their use isn’t really officially supported by the helper library in the first place. It does work because what’s passed to sendCommand gets passed to

function _toOpenhabPrimitiveType (value) {
  if (value === null) return 'NULL';
  if (value === undefined) return 'UNDEF';
  if (typeof value === 'number' || typeof value === 'string') {
    return value;
  } else if (typeof value.toOpenHabString === 'function') {
    return value.toOpenHabString();
  } else if (typeof value.toString === 'function') {
    return value.toString();
  }
  return value;
}

Note: toOpenHabString() is a function on ZonedDateTime (monkey patched on to the joda-js class) to produce an RFC??? formatted date time string expected by Java as opposed to the ISO8601 formatted string.

So you can really pass anything that has toString() as a command, but the documentation only lists those types above so I would be cautious passing anything outside those.

For completeness, here’s the sendCommand() function.

  /**
   * Sends a command to the Item.
   *
   * @example
   * // Turn on the Hallway lights
   * items.getItem('HallwayLight').sendCommand('ON');
   * // Turn on the Hallway lights for at least 5 minutes, if they were on before, keep them on, otherwise turn them off
   * items.getItem('HallwayLight').sendCommand('ON', time.Duration.ofMinutes(5));
   * // Turn on the Hallway lights for 5 minutes, then turn them off
   * items.getItem('HallwayLight').sendCommand('ON', time.Duration.ofMinutes(5), 'OFF');
   *
   * @param {string|number|ZonedDateTime|Instant|Quantity|HostState|null} value the value of the command to send, such as 'ON'
   * @param {Duration} [expire] optional duration (see {@link https://js-joda.github.io/js-joda/class/packages/core/src/Duration.js~Duration.html JS-Joda: Duration}) after which the command expires and the Item is commanded back to its previous state or `onExpire`
   * @param {string|number|ZonedDateTime|Instant|Quantity|HostState} [onExpire] the optional value of the command to apply on expire, default is the current state
   * @see sendCommandIfDifferent
   * @see postUpdate
   */
  sendCommand (value, expire, onExpire) {
    if (expire !== undefined) {
      const CACHE_KEY = this.name + '-command-expire-timeoutId';
      if (cache.private.exists(CACHE_KEY)) {
        log.debug('Cancelling existing command expire timer for {}.', this.name);
        clearTimeout(cache.private.remove(CACHE_KEY));
      }
      if (onExpire === undefined) onExpire = this.state;
      log.debug('Scheduling command expire timer for {}, will apply command {} on expire.', this.name, onExpire);
      const timeoutId = setTimeout((item, command, expiredCommand) => {
        log.debug('Command {} for {} expired: Applying command {}', expiredCommand, item.name, command);
        item.sendCommand(command);
      }, expire.toMillis(), this, onExpire, value);
      cache.private.put(CACHE_KEY, timeoutId);
    }
    if (Java.typeName(events.getClass()) === BusEventImplClassName) {
      // BusEventImpl supports providing command source
      events.sendCommand(this.rawItem, _toOpenhabPrimitiveType(value), _buildEventSource());
    } else {
      // old ScriptBusEventImpl doesn't support providing command source
      events.sendCommand(this.rawItem, _toOpenhabPrimitiveType(value));
    }
  }

I went down this path to see if there was any way it could silently fail. I don’t see any way that can happen, but I did learn you can set a timer to revert the command after a time.

I wonder then what the use of the OnOffType is. I’ve found that it only works for commands/updates, but it doesn’t work for conditionals, e.g.,

if (items.Global_TimeOfDay.state == ON) {

I’ll keep it in mind and remove its use whenever I have some time.

I applied changes 1 and 2 and tried to trigger it by sending the ON command to Override_InitializeItems, but nothing got triggered.

21:15:59.468 [INFO ] [openhab.event.ItemCommandEvent       ] - Item 'Override_InitializeItems' received command ON (source: org.openhab.ui=>org.openhab.core.io.rest$nelson.aponte)
21:16:00.279 [INFO ] [openhab.event.RuleStatusInfoEvent    ] - CheckMotion updated: RUNNING
21:16:00.341 [INFO ] [openhab.event.RuleStatusInfoEvent    ] - CheckMotion updated: IDLE
21:16:00.483 [INFO ] [openhab.event.RuleStatusInfoEvent    ] - CheckContactSensors updated: RUNNING
21:16:00.487 [INFO ] [openhab.event.RuleStatusInfoEvent    ] - CheckContactSensors updated: IDLE

Here is also the log level for the file where the rule has been defined.

When trying to run it from the MainUI I found the following error message:

Getting handler 'core.SystemStartlevelTrigger' for module '045b35fb-ecd5-4c26-9802-91afec7a547d' failed: class java.lang.String cannot be cast to class java.math.BigDecimal (java.lang.String and java.math.BigDecimal are in module java.base of loader 'bootstrap')

In JS Scripting, it has no use at all really. It might help with a little code hinting and completion in an IDE but the Helper Library has been designed around just passing the Strings "ON" and "OFF" and such.

It doesn’t work for conditionals because the .state of an Item in JS Scripting is always a String. From the docs:

  • .state ⇒ string
  • .numericState ⇒ number|null: State as number, if state can be represented as number, or null if that’s not the case
  • .quantityState ⇒ Quantity|null: Item state as Quantity or null if state is not Quantity-compatible or without unit
  • .boolState ⇒ boolean|null: Item state as boolean or null if not boolean-compatible or is NULL or UNDEF, see below for mapping of state to boolean
  • .rawState ⇒ HostState

That’s why ON, OFF and all the rest of the command and state enums are not imported from @runtime by default in the first place (if you have default imports enabled).

openhab-js goes to great lengths to present a pure JS surface for your interactions with openHAB. But openHAB is a Java program, not a JavaScript program. So openhab-js does a whole lot of converstion and translation for you. Otherwise you hit situations like this, which used to be in the JS Scripting docs until the wrapper was created so the event Object could be converted to JS for UI script users (OH 5.1):

Note that in UI based rules event.itemState, event.oldItemState, and event.itemCommand are Java types (not JavaScript), and care must be taken when comparing these with JavaScript types:… NOTE: Even with String items, simple comparison with == is not working as one would expect!

// Example assumes String item trigger
console.log(event.itemState == "test") // WRONG. Will always log "false"
console.log(event.itemState.toString() == "test") // OK

When you import ON and OFF from the runtime, you are importing Java Objects, the very thing openhab-js tries to make it so you can avoid.

To do your comparison you could use

if (items.Global_TimeOfDay.state == ON.toSring()) {

if (items.Global_TimeOfDay.rawState == ON) {

But it’s way less awkward overall to just use

if (items.Global_TimeOfDay.state == "ON") {

and that’s therefore the canonical way to do it. Note: JavasScript doesn’t really have support for enums directly but if it did or openhab-js used one of the work-arounds it still wouldn’t be less awkward than just using the Strings.

To get the state as a number use .numericState and you’ll be working with a JavaScript number.

To work with UoM, use .quantityState and you’ll get a JS Quantity which is a wrapper around the Java QuantityType<Dimension>.

Any state that can be interpreted as a boolean (e.g. Switch, Contact, Dimmer, Color,Rollershutter (I think), etc.) .boolState will return a Java true if it is “ON” and false if it is “OFF”.

In those very rare cases when you must work with the original Java State Object, you can use .rawState.


I don’t understand why that error is not showing up in your logs. I’m not sure where or what logger is responsible for logging it but it definitely should be logged when the rule is first loaded.

That seems to be the root cause of the problem. The rule is in a broken state and an UNINITIALIZED rule cannot be run under any circumstances.

That doesn’t mean the error makes sense though. As far as I can tell it looks syntactically correct. You are passing the start level number as a number. I don’t seen where it would be trying to cast a String to a BigDecimal anywhere here.

To see if the problem might be elsewhere and it’s just showing up here, what happens if you simply eliminate the triggers (i.e. pass an emptry array for the triggers)? Does the error go away in the UI? Does it change? Can you manually run the rule now?

Then add back the Item received command trigger. Does the error come back? Can you manually run the rule? Can you trigger the rule by sending the command to the Item?

Finally, add back the system started trigger. If the error is only there with the system started trigger, there might be something wrong with the openhab-js library. What verision are you using? (note you can install the openhab-js library separately which is why I ask.)

Do you get the same error with the rule builder?

Without triggers, it didn’t show any errors on the MainUI; I could also run it manually, and the logs were created.

Only with the ItemCommand trigger does it also get loaded and run by sending the command to the item. However, once I add the SystemStartLevel trigger, I see the error again (only on MainUI).

By the way, even though there is an error, I can see that MainUI can somehow parse and display it:

About the version of the JS library, I’m using auto-injection and caching the injection.

That narrows it down to the trigger.

Whatever is wrong is not widespread. There are thousands of users with SystemStartlevel triggers in use from .js files and this is the first report of the problem so there must be something unique going on here.

Next steps I think are:

  1. move the rule to a different position in the file just to make sure there isn’t some hidden character or syntax problem from some other rule in the file causing the problem.
  2. install and run with the latest version of the openhab-js library. There have been many changes made to it since OH 5.1 was released. You can either upgrade to the latest 5.2 snapshot or install the openhab-js library separately using NPM (instructions are in the docs)
  3. if that still fails file an issue.

Will try. In the meantime, here is the complete file:

// remove namespaces that are not needed by your code
//const { actions, cache, items, things, time, triggers, utils, Quantity } = require('openhab')
const { items, triggers, things } = require('openhab')
var { ON, OFF} = require('@runtime');
var Notification = require('notification')

rules.JSRule({
    name: "Initialize Items",
    description: "Initialize items on system startup",
    triggers: [triggers.SystemStartlevelTrigger(100),
        triggers.ItemCommandTrigger('Override_InitializeItems','ON')
    ],
    execute: () => {
        console.debug("System Actions> Initialize Items> Starting.");

        console.debug("System Actions> Initialize Items> Initializing scenes.");
        items.LR_Scene_Automated.sendCommand(ON);
        items.MBR_Scene_Automated.sendCommand(ON);
        items.NBR_Scene_Automated.sendCommand(ON);
        items.LR_Scene_Movie.sendCommand(OFF)

        console.debug("System Actions> Initialize Items> Initializing sensor items.");
        if (items.Global_TimeOfDay.state == "NULL") {
            items.Global_TimeOfDay.sendCommand("UNDEF");
        }
        items.Override_KT_Sensor_Illuminance.sendCommand(ON);
        items.Override_KT_Automated_Lights.sendCommand(ON);
        items.Override_KT_Sensor_Motion.sendCommand(ON);
        items.Override_MBR_Sensor_Illuminance.sendCommand(ON);
        items.Override_MBR_Sensor_Motion.sendCommand(ON);
        items.Override_MBR_Automated_Lights.sendCommand(ON);
        items.MBR_Scene_Study_White.sendCommand(OFF);
        items.MBR_Scene_Study_Yellow.sendCommand(OFF);
        items.Override_LR_Sensor_Illuminance.sendCommand(ON);
        items.Override_LR_Sensor_Motion.sendCommand(ON);
        items.LR_Scene_Study_White.sendCommand(OFF);
        items.LR_Scene_Study_Yellow.sendCommand(OFF);
        items.LR_Scene_Automated.sendCommand(ON);
        items.Override_NBR_Sensor_Illuminance.sendCommand(ON);
        items.Override_NBR_Sensor_Motion.sendCommand(ON);
        items.NBR_Scene_Study_White.sendCommand(OFF);
        items.NBR_Scene_Study_Yellow.sendCommand(OFF);
        items.Override_NBR_Automated_Lights.sendCommand(ON);
        items.Override_KT_Automated_Lights.sendCommand(ON);
        items.Override_TL_Automated_Lights.sendCommand(ON);
        items.Override_TL_Sensor_Illuminance.sendCommand(ON);
        items.Override_TL_Sensor_Motion.sendCommand(ON);
        items.Override_HW_Sensor_Motion.sendCommand(ON);
        items.Override_HW_Automated_Lights.sendCommand(ON);
        items.group_Sensors_Contact_Alert.sendCommand(OFF);
        items.group_Override_Sensors_Contact.sendCommand(ON);
        items.group_Override_Sensors_Motion.sendCommand(ON);
        /*items.Override_HW_Sensor_Illuminance.sendCommand(ON);
        items.Override_HW_Sensor_Motion.sendCommand(ON);*/


        var tempTime = time.ZonedDateTime.now();
        console.debug("System Actions> Initialize Items> Initializing plug items.");
        if (items.HM_Plug_2_Schedule_TimeOn.state === null || items.HM_Plug_2_Schedule_TimeOn.state === "UNDEF") {
            items.HM_Plug_2_Schedule_TimeOn.postUpdate(tempTime);
        }
        if (items.HM_Plug_2_Schedule_TimeOff.state === null || items.HM_Plug_2_Schedule_TimeOff.state === "UNDEF") {
            items.HM_Plug_2_Schedule_TimeOff.postUpdate(tempTime);
        }
        if (items.HM_Plug_2_Schedule_Switch.state === null || items.HM_Plug_2_Schedule_Switch.state === "UNDEF") {
            items.HM_Plug_2_Schedule_Switch.sendCommand(OFF);
        }
        if (items.HM_Plug_2_Away_Switch.state === null || items.HM_Plug_2_Away_Switch.state === "UNDEF") {
            items.HM_Plug_2_Away_Switch.sendCommand(OFF);
        }
        if (items.HM_Plug_2_Vacation_Switch.state === null || items.HM_Plug_2_Vacation_Switch.state === "UNDEF") {
            items.HM_Plug_2_Vacation_Switch.sendCommand(OFF);
        }
        if (items.HM_Plug_3_Schedule_Switch.state === null || items.HM_Plug_3_Schedule_Switch.state === "UNDEF") {
            items.HM_Plug_3_Schedule_Switch.sendCommand(OFF);
        }
        if (items.HM_Plug_3_Away_Switch.state === null || items.HM_Plug_3_Away_Switch.state === "UNDEF") {
            items.HM_Plug_3_Away_Switch.sendCommand(OFF);
        }
        if (items.HM_Plug_3_Vacation_Switch.state === null || items.HM_Plug_3_Vacation_Switch.state === "UNDEF") {
            items.HM_Plug_3_Vacation_Switch.sendCommand(OFF);
        }
        if (items.HM_Plug_3_Schedule_TimeOn.state === null || items.HM_Plug_3_Schedule_TimeOn.state === "UNDEF") {
            items.HM_Plug_3_Schedule_TimeOn.postUpdate(tempTime);
        }
        if (items.HM_Plug_3_Schedule_TimeOff.state === null || items.HM_Plug_3_Schedule_TimeOff.state === "UNDEF") {
            items.HM_Plug_3_Schedule_TimeOff.postUpdate(tempTime);
        }
        if (items.group_LR_PowerStrip_1_Switch.state === null || items.group_LR_PowerStrip_1_Switch.state === "UNDEF") {
            items.group_LR_PowerStrip_1_Switch.sendCommand(OFF);
        }
        console.debug("System Actions> Initialize Items> Initializing time for non-persisted datetime items.");
        var currentTime = time.ZonedDateTime.now();
        if (items.LR_PowerStrip_1_Socket1_Schedule_TimeOn.state === null || items.LR_PowerStrip_1_Socket1_Schedule_TimeOn.state === "UNDEF") {
            var tempTime = currentTime.withHour(10).withMinute(0).withSecond(0).withNano(0);
            items.LR_PowerStrip_1_Socket1_Schedule_TimeOn.postUpdate(tempTime);
        }
        if (items.LR_PowerStrip_1_Socket2_Schedule_TimeOn.state === null || items.LR_PowerStrip_1_Socket2_Schedule_TimeOn.state === "UNDEF") {
            var tempTime = currentTime.withHour(10).withMinute(0).withSecond(0).withNano(0);
            items.LR_PowerStrip_1_Socket2_Schedule_TimeOn.postUpdate(tempTime);
        }
        if (items.LR_PowerStrip_1_Socket3_Schedule_TimeOn.state === null || items.LR_PowerStrip_1_Socket3_Schedule_TimeOn.state === "UNDEF") {
            var tempTime = currentTime.withHour(10).withMinute(0).withSecond(0).withNano(0);
            items.LR_PowerStrip_1_Socket3_Schedule_TimeOn.postUpdate(tempTime);
        }
        if (items.LR_PowerStrip_1_Socket1_Schedule_TimeOff.state === null || items.LR_PowerStrip_1_Socket1_Schedule_TimeOff.state === "UNDEF") {
            var tempTime = currentTime.withHour(22).withMinute(0).withSecond(0).withNano(0);
            items.LR_PowerStrip_1_Socket1_Schedule_TimeOff.postUpdate(tempTime);
        }
        if (items.LR_PowerStrip_1_Socket2_Schedule_TimeOff.state === null || items.LR_PowerStrip_1_Socket2_Schedule_TimeOff.state === "UNDEF") {
            var tempTime = currentTime.withHour(22).withMinute(0).withSecond(0).withNano(0);
            items.LR_PowerStrip_1_Socket2_Schedule_TimeOff.postUpdate(tempTime);
        }
        if (items.LR_PowerStrip_1_Socket3_Schedule_TimeOff.state === null || items.LR_PowerStrip_1_Socket3_Schedule_TimeOff.state === "UNDEF") {
            var tempTime = currentTime.withHour(22).withMinute(0).withSecond(0).withNano(0);
            items.LR_PowerStrip_1_Socket3_Schedule_TimeOff.postUpdate(tempTime);
        }
        console.debug("System Actions> Initialize Items> Initializing Roomba items.");
        if (items.Roomba_Space_MBR.state === null || items.Roomba_Space_MBR.state === "UNDEF") {
            items.Roomba_Space_MBR.sendCommand(OFF);
            items.Roomba_Space_MBR_Position.postUpdate(0);
        }
        if (items.Roomba_Space_NBR.state === null || items.Roomba_Space_NBR.state === "UNDEF") {
            items.Roomba_Space_NBR.sendCommand(OFF);
            items.Roomba_Space_NBR_Position.postUpdate(0);
        }
        if (items.Roomba_Space_LR.state === null || items.Roomba_Space_LR.state === "UNDEF") {
            items.Roomba_Space_LR.sendCommand(OFF);
            items.Roomba_Space_LR_Position.postUpdate(0);
        }
        if (items.Roomba_Space_DT.state === null || items.Roomba_Space_DT.state === "UNDEF") {
            items.Roomba_Space_DT.sendCommand(OFF);
            items.Roomba_Space_DT_Position.postUpdate(0);
        }
        if (items.Roomba_Space_Carpet.state === null || items.Roomba_Space_Carpet.state === "UNDEF") {
            items.Roomba_Space_Carpet.sendCommand(OFF);
            items.Roomba_Space_Carpet_Position.postUpdate(0);
        }
        if (items.Roomba_Space_TL.state === null || items.Roomba_Space_TL.state === "UNDEF") {
            items.Roomba_Space_TL.sendCommand(OFF);
            items.Roomba_Space_TL_Position.postUpdate(0);
        }
        if (items.Roomba_Space_BR.state === null || items.Roomba_Space_BR.state === "UNDEF") {
            items.Roomba_Space_BR.sendCommand(OFF);
            items.Roomba_Space_BR_Position.postUpdate(0);
        }
        if (items.Roomba_Space_KT.state === null || items.Roomba_Space_KT.state === "UNDEF") {
            items.Roomba_Space_KT.sendCommand(OFF);
            items.Roomba_Space_KT_Position.postUpdate(0);
        }
        if (items.Roomba_Space_HW.state === null || items.Roomba_Space_HW.state === "UNDEF") {
            items.Roomba_Space_HW.sendCommand(OFF);
            items.Roomba_Space_HW_Position.postUpdate(0);
        }
        if (items.Roomba_Space_EW.state === null || items.Roomba_Space_EW.state === "UNDEF") {
            items.Roomba_Space_EW.sendCommand(OFF);
            items.Roomba_Space_EW_Position.postUpdate(0);
        }
        if (items.Roomba_Space_Carpet_ID.state === null || items.Roomba_Space_Carpet_ID.state === "UNDEF") {
            items.Roomba_Space_Carpet_ID.postUpdate(0);
        }
        if (items.Roomba_Space_DT_ID.state === null || items.Roomba_Space_DT_ID.state === "UNDEF") {
            items.Roomba_Space_DT_ID.postUpdate(1);
        }
        if (items.Roomba_Space_EW_ID.state === null || items.Roomba_Space_EW_ID.state === "UNDEF") {
            items.Roomba_Space_EW_ID.postUpdate(4);
        }
        if (items.Roomba_Space_BR_ID.state === null || items.Roomba_Space_BR_ID.state === "UNDEF") {
            items.Roomba_Space_BR_ID.postUpdate(11);
        }
        if (items.Roomba_Space_KT_ID.state === null || items.Roomba_Space_KT_ID.state === "UNDEF") {
            items.Roomba_Space_KT_ID.postUpdate(14);
        }
        if (items.Roomba_Space_TL_ID.state === null || items.Roomba_Space_TL_ID.state === "UNDEF") {
            items.Roomba_Space_TL_ID.postUpdate(15);
        }
        if (items.Roomba_Space_MBR_ID.state === null || items.Roomba_Space_MBR_ID.state === "UNDEF") {
            items.Roomba_Space_MBR_ID.postUpdate(16);
        }
        if (items.Roomba_Space_NBR_ID.state === null || items.Roomba_Space_NBR_ID.state === "UNDEF") {
            items.Roomba_Space_NBR_ID.postUpdate(17);
        }
        if (items.Roomba_Space_LR_ID.state === null || items.Roomba_Space_LR_ID.state === "UNDEF") {
            items.Roomba_Space_LR_ID.postUpdate(18);
        }
        if (items.Roomba_Space_HW_ID.state === null || items.Roomba_Space_HW_ID.state === "UNDEF") {
            items.Roomba_Space_HW_ID.postUpdate(19);
        }

        console.debug("System Actions> Initialize Items> Initializing other items.");
        if (items.HM_Temperature_Threshold_Overheating.state === null || items.HM_Temperature_Threshold_Overheating.state === "UNDEF") {
            items.HM_Temperature_Threshold_Overheating.postUpdate(2);
        }

        console.debug("System Actions> Initialize Items> Ending.");
    },
    tags: ["System", "Initialization"],
    id: "InitializeItems"
});


rules.JSRule({
    name: "Report Offline Thing",
    description: "Report offline things and try to restart them.",
    triggers: [triggers.ThingStatusChangeTrigger("ONLINE", "OFFLINE")], //TODO: Check if this trigger works without specifying a thing ID
    execute: (event) => {
        console.info("Report Offline Thing > STARTING.")
        console.info("Report Offline Thing > Triggering Thing: %s.", event.thingUID)
        const thing = things.getThing(event.thingUID) //TODO: Check this function call
        console.info("Report Offline Thing > Found Thing: %s.", thing.label)
        console.info("Report Offline Thing > Waiting for 5 minutes for the Thing to automatically come back online.")
        setTimeout(() => {
            console.info("Report Offline Thing > Timer 1 > Stored Thing: %s.", thing.label)
            console.info("Report Offline Thing > Timer 1 > Event Thing: %s.", event.thingUID)
            if (thing.status !== "ONLINE") {
                console.info("Report Offline Thing > Timer 1 > Restarting Thing.")
                thing.setEnabled(true)
                console.info("Report Offline Thing > Timer 1 > Waiting for Thing to restart.")
                setTimeout(() => {
                    console.info("Report Offline Thing > Timer 2 > Checking the status of the %s.", thing.label)
                    console.info("Report Offline Thing > Timer 2 > Event Thing: %s.", event.thingUID)
                    if (thing.status === "ONLINE") {
                        console.info("Report Offline Thing > Timer 2 > The Thing is online.")
                        Notification.notify("Rosie > The %s changed to %s at %s, but I restarted it. Event thing: %s", thing.label, thing.status, new Date().toLocaleTimeString(), event.thingUID)
                        console.info("Report Offline Thing > Timer 2 > Notification sent.")
                    } else {
                        console.info("Report Offline Thing > Timer 2 > The Thing is still offline.")
                        Notification.alert("Rosie > The %s changed to %s at %s. I tried my best, but I couldn't restart it. Make sure it is powered on. Event thing: %s", thing.label, thing.status, new Date().toLocaleTimeString(), event.thingUID)
                        console.info("Report Offline Thing > Timer 2 > Notification sent.")
                    }
                    console.info("Report Offline Thing > Timer 2 > ENDING.")
                }, 50 * 1000)
            } else {
                console.info("Report Offline Thing > Timer 1 > Thing automatically restarted. Reseting the variables")
            }
            console.info("Report Offline Thing > Timer 1 > ENDING.")
        }, 5 * 60 * 1000)
        console.info("Report Offline Thing > ENDING.")
    },
    tags: ["System", "Notifications"],
    id: "ReportOfflineThing"
})

I swapped the position of the rules as @rlkoshak suggested, and now I can see the message in the logs:

info_circle 06:28:41.543	INFO	
org.openhab.automation.jsscripting.openhab-js.rules
Adding rule: Initialize Items
info_circle 06:28:41.546	INFO	
openhab.event.RuleStatusInfoEvent
InitializeItems updated: UNINITIALIZED
info_circle 06:28:41.547	INFO	
openhab.event.RuleStatusInfoEvent
InitializeItems updated: INITIALIZING
info_circle 06:28:41.550	INFO	
openhab.event.RuleStatusInfoEvent
InitializeItems updated: UNINITIALIZED (HANDLER_INITIALIZING_ERROR): Getting handler 'core.SystemStartlevelTrigger' for module 'b41967c9-1e6e-4f80-bf83-f42281135ef5' failed: class java.lang.String cannot be cast to class java.math.BigDecimal (java.lang.String and java.math.BigDecimal are in module java.base of loader 'bootstrap')
info_circle 06:29:00.281

Even after reducing the rule to the following, the same message was there

rules.JSRule({
    name: "Initialize Items",
    description: "Initialize items on system startup",
    triggers: [triggers.SystemStartlevelTrigger(100),
        triggers.ItemCommandTrigger('Override_InitializeItems','ON')
    ],
    execute: () => {
        console.debug("System Actions> Initialize Items> Starting.");

        console.debug("System Actions> Initialize Items> Initializing scenes.");
       

        console.debug("System Actions> Initialize Items> Ending.");
    },
    tags: ["System", "Initialization"],
    id: "InitializeItems"
});

@rlkoshak, can you also reproduce the error? That way I can create the bug.

I don’t have acces to write a rule as a text file right now so I can’t test this out. If I remember I can try later today but I wouldn’t wait on my to file an issue.

I tested to create that rule (and create an Item with the appropriate name) on my local development setup, only changing the logging to warn since I don’t have debug logging enabled for that namespace. This is what is logged during OH startup:

20:31:53.488 [WARN ] (le-InitializeItems-1) [tomation.jsscripting.file.bugtest.js] - System Actions> Initialize Items> Starting.
20:31:53.489 [WARN ] (le-InitializeItems-1) [tomation.jsscripting.file.bugtest.js] - System Actions> Initialize Items> Initializing scenes.
20:31:53.490 [WARN ] (le-InitializeItems-1) [tomation.jsscripting.file.bugtest.js] - System Actions> Initialize Items> Ending.
20:31:53.491 [DEBUG] (le-InitializeItems-1) [e.automation.internal.RuleEngineImpl] - The rule 'InitializeItems' was executed.

I can’t seem to find any error logged. So, I’m not sure that a bug report is needed.

I’m running this on latest 5.2.0 with these two still unmerged patches that deal with some issues related to startlevel triggering, among other things:

I can’t say for sure if any of the above PRs specifically solves the problem, or if it has been solved previously (since 5.1.3), but as far as I can tell, it’s running fine with these PRs.