Now it's clear   instead of   (%arr 0)  you simply should write (%arr>0)  
The ObjectScript compiler is interpreting the blank after %arr as an argument terminator

Strange.  It should generate   IF (3>0) {QUIT 5} and accept it.
Could you pls simplify the case for testing to 

#define TestIf(%arr) if%arr>0QUIT5

Not yet Halloween, but this looks spooky:
For me, all variants work: 
My versions:
InterSystems Studio Client  2024.1.0 Build 262
Server IRIS for Windows (x86-64) 2024.3 (Build 217U)

So this means that the IF is not applicable in your context.
What commands are before the $$$TestIf(3) and after  ? 
I think of some  WRITE  $$$TestIf(3) .....    
Or you may try to explicitly write the macro-generated code to see any hidden issue
I'm running a bit out of fantas,y what may go on 

Thanks for the correction.
I had something similar in mind, but didn't find the related doc!

TestFor.inc
 

#define MyLoop(%count) setx=""for i=1:1:%countsetx=$order(^%SYS("JOURNAL",x),-1) writex,! 

in Test class:
 

ClassMethod Mike()
{
	$$$MyLoop(7) Write ?5,$get(@$ZR," *** "),!
}	

Resulting in

PURGED
      ***
PREFIX
 
MAXSIZE
     1073741824
LIFESPAN
      ***
LAST
     1^C:\InterSystems\IRIS242\mgr\journal\20251029.003
EXPSIZE
     0
CURRENT
     1^C:\InterSystems\IRIS242\mgr\journal\20251029.003

1) you miss a final condition in $SELECT(). It's the 1:
$SELECT(^GlFSL("Debug")>0:Entry^HS.Local.VA.Util.Log(%arr,,"D"),1:QUIT)
2) QUIT doesn't return a value but <UNDEFINED> error if you don't have 
a SET QUIT=""  somwhere before or use $GET()
this may fit

$SELECT(^GlFSL("Debug")>0:Entry^HS.Local.VA.Util.Log(%arr,,"D"),1:$GET(QUIT))

Command QUIT is just appropriate with $CASE(...)
https://docs.intersystems.com/iris20252/csp/docbook/DocBook.UI.Page.cls?KEY=RCOS_fselect#RCOS_fselect_select_and_case

Thank you @Dmitry Maslennikov !
You confirmed my initial suspicion.

And the missing intersystemsdc version (including preinstalled ZPM) 
affects a rather broad range of packages in OEX.

technically correct but not really a practical solution
for 50+ affected packages in  OEX  

That means that the -ml- versions are requested in Dockerfile or docker-compose.yml.
It is not immediately visible that ML is required and used.
For a few packages, it was pretty obvious that
it came in by cut&paste from previous packages..

Yeah!
If there is a reference of how to add -ml- functionality to available intersystemsds/iris-community and intersystemsdc/irishealth-community 
The other possibility could be to change to NON-intersystemsdc versions
and add the single-line installation for ZPM.  Not my favorite.  

In most cases, I've seen working before
the real message was "community license expired."
You see it only in the builder log. OR
using  docker compose --progress plain build  from command line.
workaround:
use instead.  intersystemsds/iris-community or intersystemsdc/irishealth-community  
:latest is always the default

Hi @Evgeny Shvarov 
You inspired me to extend the standard Dockerfile sequence by this line

RUN --mount=type=bind,src=.,dst=. \
    iris start IRIS && \
    iris session IRIS < zpm.script && \
    iris session IRIS < iris.script && \
    iris stop IRIS quietly

and zpm.script is basically the version-independent one-liner sliced to readable pieces

zn "%SYS"
 ;; from onezpm
hang 3
write !,"from onezpm",!
set r=##class(%Net.HttpRequest).%New()
set r.Server="pm.community.intersystems.com"
set r.SSLConfiguration="ISC.FeatureTracker.SSL.Config"
do r.Get("/packages/zpm/latest/installer")
do $system.OBJ.LoadStream(r.HttpResponse.Data,"c")
ZPM "repo -r -n registry -url https://pm.community.intersystems.com/ -user """" -pass """""
zpm "enable -community"
hang 2
Write !,"ZPM ready",!
halt

This makes me independent from the limits of intersystemsdc/.....
and I can use images from 
containers.intersystems.com/intersystems/****-community
with a minimal invasive approach without touching any other part of the repo