When you run $zf(-100) from IRIS session terminal the external process is run in the OS context (secutity/permissions) of the OS user loggen in.

When $zf(-100) is run by a storedproc or studio is run in the OS context (secutity/permissions) of the OS user used by the IRIS instance.

You have permission and/or environment issue.

Why run python using $zf(-100)? You can use embedded python to avoid this issues, it is simpler and have better performance.

I'm not sure what "HL7 Reference Guide" exactly means for you, however, within "health enabled products" (IRIS for Health, Healthhare Connect, Healthshare UCR etc.) there are "HL7 Schemas" for all HL7 v2 variants up to 2.8.2.

Can be accessed from Management Portal Interoperability -> Interoperate -> HL7 v2.x -> HL7 v2.x Schema Structures.

There, for each version you can browse in detail the HL7 message structure, segments, field, subfields etc down to code tables associated to coded entries/fields.

If you don't have IRIS for Health, you can download IRIS for Health community edition that is free for non commercial/production use (check license for details).

This is interesting.

It is evident that when the class is compiled IRIS parse the <PropertyName>Computation() method(s) to find out what properties are actually used/referenced/passed to the cols.getfield() method(s), then it use this information to set the "fields" multidimensional property of %Library.PropertyHelper class before calling the <PropertyName>Computation() method.
This way only the used properties are set in the "fields" multidimensional property of %Library.PropertyHelper class.
This optimization improves performance in case of a class with many properties, possibly "complex" properties (calculated, references etc.) and I believe this is why has been implemented.

The "parser" is...simple, very simple.

To prove this assumption I wrote a little sample:

Class Community.Computation Extends %Persistent
{

Property FirstName As %String;
Property LastName As %String;
Property FullName As %String [ SqlComputed ];
ClassMethod FullNameComputation(cols As %Library.PropertyHelper) As %String
{
    ; cols.getfield("FirstName")
    ; cols.getfield("LastName")
    return ..FullNameComputationSub(cols,"FirstName","LastName")
}

ClassMethod FullNameComputationSub(cols As %Library.PropertyHelper, p1 As %String, p2 As %String) As %String
{
    return cols.getfield(p1)_" "_cols.getfield(p2)
}

/// do ##class(Community.Computation).test()
ClassMethod test()
{
    set obj=..%New()
    set obj.FirstName="Enrico"
    set obj.LastName="Parisi"
    write obj.FullName,!
}

}

If I run test() I get:
 

do ##class(Community.Computation).test()
Enrico Parisi

If I remove the commented line "; cols.getfield("FirstName")" and run test() again:

do ##class(Community.Computation).test()
 Parisi

If you look at your error:

"set cols.fields("ropert")={ropert}'"

That's the parser that found "cols.getfield(property)" and assuming a string was passed removed the first and last characters (assuming were double quotes), so it got "ropert".

Bottom line, cols.fields() can only be used passing a string constant with a property name.

My guess (I may be wrong!) is that you did not configure IIS existingResponse PassThrough option.

In IIS, if you don't configure that options, application errors (like IRIS REST errors) are not sent back to the client, instead a "standard IIS error" (my definition) is sent back to the client (i.e. browser).

Check this IRIS documentation on Configuring IIS to Return SOAP Fault Details, although it refers to soap, the same apply to REST.
You may want to google "IIS existingResponse PassThrough" for more info.

Again, I may be wrong...but I bet on this being the issue here.

First I'd suggest not to use a persistent class "linked" to a message (Ens.Response in this case), Supplier  is linked by your message class in this case.
If you do it, you will definitely create "orphaned" persistent objects when you purge, unless you add some logic (like triggers and callbacks) to delete the "linked" persistent objects when a message is purged.

To avoid this (when possible) a serial class is preferred.

So, the Supplier class would be:

Class Community.App.Msg.Supplier Extends (%SerialObject, %XML.Adaptor)
{
Property row As %Integer;
}

As for the message class:

Class Community.App.Msg.Suppliers Extends Ens.Response
{

Property Supplier As list Of Community.App.Msg.Supplier(XMLPROJECTION = "ELEMENT");
ClassMethod test() As %Status
{
    set XmlString="<Suppliers><Supplier><row>1</row></Supplier><Supplier><row>2</row></Supplier></Suppliers>"
    set reader = ##class(%XML.Reader).%New()
    $$$ThrowOnError(reader.OpenString(XmlString))
    do reader.CorrelateRoot("Community.App.Msg.Suppliers")
    do reader.Next(.Suppliers, .tSC)
    do Suppliers.XMLExport(,",indent")
    quit tSC
}
}

For simplicity I modified the sample to be a classmethod.
When the test() method is run the output is:

EPTEST>d ##class(Community.App.Msg.Suppliers).test()
<Suppliers>
  <Supplier>
    <row>1</row>
  </Supplier>
  <Supplier>
    <row>2</row>
  </Supplier>
</Suppliers>

The relevant documentation is "Controlling the Form of the Projection for Collection Properties" here.

Let me add a few notes.

If a class extend Ens.Response or Ens.Request  is not necessary to extend %Persistent because is already inherited by Ens.Request/Ens.Response.
Edit: please see Antoine commnet below

If the desired XML tag correspond to the class name (without package), it is not necessary to add the XMLNAME parameter, like you did in App.Objects.Suppliers class.

Same goes for XMLNAME property parameter XMLNAME = "row" is not necessary because the property name correspond to the desired XML tag name.