MacOS – launchd runs program every hour even though StartCalendarInterval array is provided

launchdmacos

I have my StartCalendarInterval set in my launchd plist file like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>local.script.launcher</string>
        
        <key>Program</key>
        <string>/usr/bin/osascript</string>
        
        <key>ProgramArguments</key>
        <array>
            <string>osascript</string>
            <string>/Users/me/basic-script.scpt</string>
        </array>
        
        <key>StartCalendarInterval</key>
        <array>
            <dict>
                <key>Hour</key>
                <integer>8</integer>
                <key>Minute</key>
                <integer>0</integer>
            </dict>
            <dict>
                <key>Hour</key>
                <integer>16</integer>
                <key>Minute</key>
                <integer>0</integer>
            </dict>
            <dict>
                <key>Hour</key>
                <integer>24</integer>
                <key>Minute</key>
                <integer>0</integer>
            </dict>
        </array>
    </dict>
</plist>

Even though I am declaring 3 different StartCalendarIntervals, the agent still launches the program every hour.

What am I doing wrong?

.

SOLUTION:

As per @Phong's answer, for launchd plist files and StartCalendarInterval, midnight, 12AM, or 2400 hours military time is Hour = 0 not 24.

Best Answer

launchd is throwing out 24 as an invalid Hour value, thus interpreting that entire entry as Minute = 0. This causes your agent to run every hour on the dot.

The correct value for midnight is 0:

<dict>
    <key>Hour</key>
    <integer>0</integer>

    <key>Minute</key>
    <integer>0</integer>
</dict>