Skip to main content

Passing a structure (ExtensionObject) argument

Some methods take a structure, not a number or a string. In OPC UA such a value travels as an ExtensionObject. This page shows the three ways to pass one, and the mistake that accounts for most of the reports we get.

The rule​

msg.payload holds one property per input argument, named exactly as the server declares it.

msg.payload = {
Setting: { // the name of the argument, from the server
Duration: 23,
Cycles: 10,
DataAvailable: true
}
};

The name is not yours to choose. Setting and Settings are two different properties, and the second one never reaches the method. Press Check in the node, read the names the server reports, and use the copy button to get a template.

A plain object is enough. The Call node reads the data type of the argument from the server and builds the ExtensionObject itself, so you do not have to write the type.

Without an ExtensionObject node​

For most methods this is all you need: an inject or a function node that sets the payload.

// Function node, in front of the Call node
msg.payload = {
Setting: { Duration: 23, Cycles: 10, DataAvailable: true }
};
return msg;

Flow: inject → function → Call

With an ExtensionObject node​

The ExtensionObject node builds a structure and puts it in msg.payload. That payload is the structure itself, not a map of arguments, so one step has to move it under the argument's name:

// Function node, between the ExtensionObject node and the Call node
msg.payload = { Setting: msg.payload };
return msg;

Flow: inject → ExtensionObject → function → Call

Leave that step out and the Call node has no property named Setting. It then tells you so, and names the arguments the method expects.

Use this route when you want the node's editor to build the structure for you, when the same structure feeds several nodes, or when a value of the structure comes from elsewhere in the flow.

The explicit forms​

If you already hold an encoded structure, pass it as it is. Both OPC UA JSON forms are accepted — 1.05, with UaTypeId and UaBody:

msg.payload = {
Setting: {
UaTypeId: "ns=2;i=1001",
UaBody: { Duration: 23, Cycles: 10, DataAvailable: true }
}
};

and 1.04, with TypeId and Body:

msg.payload = {
Setting: {
TypeId: "ns=2;i=1001",
Body: { Duration: 23, Cycles: 10, DataAvailable: true }
}
};

Prefer the plain object of the first section. A type you write by hand is a type that can be wrong; a type read from the server cannot.

An array of structures​

An argument whose value rank is 1 takes an array. Each element follows the same rules:

msg.payload = {
Settings: [
{ Duration: 23, Cycles: 10, DataAvailable: true },
{ Duration: 42, Cycles: 1, DataAvailable: false }
]
};

When it does not work​

What you seeWhat it means
msg.payload carries no input argument "X"the property is missing or misspelled. The message lists the arguments the method expects and the properties your payload holds — compare the two.
a warning that an argument was sent as its defaultthe same mistake on a number or a string argument. The call went through with 0 or "".
Cannot read properties of undefined (reading 'Value')the same mistake, on a version released before this page. Check the property names.
BadInvalidArgument from the serverthe names match, but a field inside the structure does not, or has the wrong type. Compare the fields with the type definition in the address space.