executing script DynDNS from scheduler failed, please check it manually

I have searched and read a number of threads on this.

My guess is that there is something about the code below that is causing the error.

I believe that the error only occurs when a DNS update is required.

/system script
add dont-require-permissions=no name=dyndns owner=admin policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon source="\r\
    \n/system\r\
    \n:local cdate [clock get date] \r\
    \n:local yyyy  [:pick \$cdate 0  4]\r\
    \n:local MM    [:pick \$cdate 5  7]\r\
    \n:local dd    [:pick \$cdate 8 10]\r\
    \n:local identitydate \"\$[identity get name]_\$yyyy-\$MM-\$dd\"\r\
    \n#/export show-sensitive file=\"\$identitydate\"\r\
    \n\r\
    \n# Export public IP and mail it\r\
    \n\r\
    \n/ip/address print file=\"\$identitydate-IP\"\r\
    \n\r\
    \n/tool fetch upload=yes mode=ftp ascii=no src-path=\"\$identitydate-IP\" dst-path=\"/mikrotik-backups/\$identitydate-IP.txt\" address=192.168.2.22 port=21 user=mikrotik password=mikrotik\r\
    \n\r\
    \n/file remove \"IP-\$[\$identitydate].txt\"\r\
    \n\r\
    \n# Set needed variables\r\
    \n\t:local username \"xxxxxxxxxxxx\"\r\
    \n\t:local clientkey \"xxxxxxxxx\"\r\
    \n\t:local hostname \"xxxxxxx.dyndns.org\"\r\
    \n\r\
    \n\t:global dyndnsForce\r\
    \n\t:global previousIP\r\
    \n\r\
    \n# get the current IP address from the internet (in case of double-nat)\r\
    \n\t/tool fetch mode=http address=\"checkip.dyndns.org\" src-path=\"/\" dst-path=\"/dyndns.checkip.html\"\r\
    \n\t:delay 1\r\
    \n\t:local result [/file get dyndns.checkip.html contents]\r\
    \n\r\
    \n# parse the current IP result\r\
    \n\t:local resultLen [:len \$result]\r\
    \n\t:local startLoc [:find \$result \": \" -1]\r\
    \n\t:set startLoc (\$startLoc + 2)\r\
    \n\t:local endLoc [:find \$result \"</body>\" -1]\r\
    \n\t:local currentIP [:pick \$result \$startLoc \$endLoc]\r\
    \n\t:log info \"UpdateDynDNS: currentIP = \$currentIP\"\r\
    \n\r\
    \n# Remove the # on next line to force an update every single time - useful for debugging,\r\
    \n# but you could end up getting blacklisted by DynDNS!\r\
    \n\r\
    \n#:set dyndnsForce true\r\
    \n\r\
    \n# Determine if dyndns update is needed\r\
    \n# more dyndns updater request details https://help.dyn.com/remote-access-api/perform-update/\r\
    \n\t:log info \"UpdateDynDNS: previousIP = \$previousIP\"\r\
    \n\t:if (\$dyndnsForce = true) do={ :log warning \"UpdateDynDNS: Forced update on\" }\r\
    \n\r\
    \n\t:if ((\$currentIP != \$previousIP) || (\$dyndnsForce = true)) do={\r\
    \n\t\t:set dyndnsForce false\r\
    \n\t\t:set previousIP \$currentIP\r\
    \n\r\
    \n\t\t/tool fetch mode=https \\\r\
    \n\t\turl=\"https://\$username:\$clientkey@members.dyndns.org/v3/update\?hostname=\$hostname&myip=\$currentIP\" \\ \r\
    \n\t\tdst-path=\"/dyndns.txt\"\r\
    \n\r\
    \n\t\t:delay 1\r\
    \n\t\t:local result [/file get dyndns.txt contents]\r\
    \n\t\t:log info (\"UpdateDynDNS: Dyndns update needed\")\r\
    \n\t\t:log info (\"UpdateDynDNS: Dyndns Update Result: \".\$result)\r\
    \n\t\t:put (\"Dyndns Update Result: \".\$result)\r\
    \n\t} else={\r\
    \n\t\t:log info (\"UpdateDynDNS: No dyndns update needed\")\r\
    \n\t}\r\
    \n\r\
    \n"

These are the log entries:
Screenshot 2025-02-18 071630.jpg
This is the scheduler config (for this one script):

/system scheduler
add interval=1d name=DynDNS on-event=DynDNS policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon start-date=2022-10-18 start-time=02:00:00

Thank you.

Already tried to run the script from command line ?
You should get an error indication then (if something was wrong).

Well, I pasted the script directly into a Terminal window, ignored the large number of errors and failures, and the log entries did not show an error.

Run the script from terminal, not paste on terminal.

/system script run

Thank you (embarresed-I-didn’t-know-that emoji inserted here).

No dyndns change needed and no error in log.

Set dyndnsForce to true and ran it again – still no error in log.

Perhaps an interaction between requiring a dyndns update AND scheduler?

Are you sure about that interval ?
From the screenshot of your logfile, it runs every second ? Or are those manual runs ?

And maybe change this
dont-require-permissions=no
to
dont-require-permissions=yes

This might do :laughing:

:open_mouth:
or
:astonished:

So I started to write the following:

I use Winbox often instead of the CLI, where it shows this:
Screenshot 2025-02-18 081303.png
The “Don’t Require Permissions” checkbox is checked. Doesn’t that mean “dont-require-permissions=yes”

And yet, the export does indeed show “dont-require-permissions=no”

when I realized I have 2 different scripts (see if you can tell the difference):

dyndns
DynDNS

Ugh – I think the system (but more likely I) was confusing them somewhere along the way.

Troubleshooting now…will summarize my findings…

Still can’t get this fixed.

Using a form of brute force troubleshooting, I’m pretty sure I’ve isolated the problem as occuring only when there is a change in IP number, and probably stemming from this line (4th from end of script) in the script:

/file remove "$identitydate-IP.txt"

This is the script that is causing the error:

/system
:local cdate [clock get date] 
:local yyyy  [:pick $cdate 0  4]
:local MM    [:pick $cdate 5  7]
:local dd    [:pick $cdate 8 10]
:local identitydate "$[identity get name]_$yyyy-$MM-$dd"
#/export show-sensitive file="$identitydate"
# Export public IP and mail it
#/ip/address print file="$identitydate-IP"
#/tool fetch upload=yes mode=ftp ascii=no src-path="$[$identitydate]-IP.txt" dst-path="/mikrotik-backups/$[$identitydate]-IP.txt" address=192.168.2.22 port=21 user=mikrotik password=mikrotik
#/file remove "$identitydate-IP.txt"
# Set needed variables
	:local username "<dyndns-username"
	:local clientkey "9axxxxx"
	:local hostname "<host>.dyndns.org"
	:global dyndnsForce
	:global previousIP
# get the current IP address from the internet (in case of double-nat)
	/tool fetch mode=http address="checkip.dyndns.org" src-path="/" dst-path="/dyndns.checkip.html"
	:delay 1
	:local result [/file get dyndns.checkip.html contents]
# parse the current IP result
	:local resultLen [:len $result]
	:local startLoc [:find $result ": " -1]
	:set startLoc ($startLoc + 2)
	:local endLoc [:find $result "</body>" -1]
	:local currentIP [:pick $result $startLoc $endLoc]
	:log info "UpdateDynDNS: currentIP = $currentIP"
# Remove the # on next line to force an update every single time - useful for debugging,
# but you could end up getting blacklisted by DynDNS!
#:set dyndnsForce true
# Determine if dyndns update is needed
# more dyndns updater request details https://help.dyn.com/remote-access-api/perform-update/
	:log info "UpdateDynDNS: previousIP = $previousIP"
	:if ($dyndnsForce = true) do={ :log warning "UpdateDynDNS: Forced update on" }
	:if (($currentIP != $previousIP) || ($dyndnsForce = true)) do={
		:set dyndnsForce false
		:set previousIP $currentIP
		/tool fetch mode=https \
		url="https://$username:$clientkey@members.dyndns.org/v3/update?hostname=$hostname&myip=$currentIP" \ 
		dst-path="/dyndns.txt"
		:delay 5
		:local result [/file get dyndns.txt contents]
		:log info ("UpdateDynDNS: Dyndns update needed")
		:log info ("UpdateDynDNS: Dyndns Update Result: ".$result)
		:put ("Dyndns Update Result: ".$result)
                                           /ip/address print file="$identitydate-IP"
                                          /tool fetch upload=yes mode=ftp ascii=no src-path="$[$identitydate]-IP.txt" dst-path="/mikrotik-backups/$[$identitydate]-IP.txt" address=192.168.2.22 port=21 user=mikrotik password=mikrotik
                                          /file remove "$identitydate-IP"
	} else={:log info ("UpdateDynDNS: No dyndns update needed")}
:set dyndnsForce
:set previousIP

What /system is for?

for localize all commands without write in every line /system,
on this case only date is used, but also gmt-offset, time-zone-autodetect, dst-active, time, time-zone-name can be obtained without write everytime /system

/system
:local cdate [clock get date]

is the same to

:local cdate [/system clock get date]

Is a code taken to my 2023-06-27 script:
http://forum.mikrotik.com/t/scripts-using-dates-broken/167677/3

That was a quick example, but to shorten it properly it should be done like this:

/system clock
:global strDate [get date]
:global strTime [get time]
:global intGoff [:tonum [get gmt-offset]]

I know that … wrong question asked: What is the purpose of that?
Just for a few commands? All others are fully qualified so maybe the wrong default context set with /system is the problem?

Is there any reason why the following line would cause an error (possibly only when called by scheduler):

/file remove "$identitydate-IP.txt"

Files look like this:

Screenshot 2025-02-27 064243.png
The file:

212RB5009_2025-02-27-IP.txt

was created with this code (in the script):

/system
:local cdate [clock get date] 
:local yyyy  [:pick $cdate 0  4]
:local MM    [:pick $cdate 5  7]
:local dd    [:pick $cdate 8 10]
:local identitydate "$[identity get name]_$yyyy-$MM-$dd"

Followed by the following inside the “if” used to determine is a dyndns update is required:

                                           /ip/address print file="$identitydate-IP"

remove want one array of one or more IDs as parameter

/file remove [find where name="$identitydate-IP.txt"]

no matter if on terminal this or that work or not.

Do I understand correctly that "remove" wants an ID number, and not a quoted file name?

I have made the change and will report back.