Configuration TEXT parameter “transformationPattern”

Not sure where to put this; Recently added a new switch via the code tab and when I saved it, I had a message like this for every switch (all my mains switches are in one generic MQTT thing).

2026-07-08 17:15:36.409 [INFO ] [ml.internal.things.YamlThingProvider] - “mqtt:topic:f06f8352c2:Switches:Garage_Lights_n”: the value of the configuration TEXT parameter “transformationPattern” is not interpreted as a string and will be automatically converted. Enclose your value in double quotes to prevent conversion. Based on code like this;

  Garage_Lights_n:
    type: switch
    label: Garage Lights
    config:
      stateTopic: zwave1/Lights_-_105/switch_binary/endpoint_2/currentValue
      commandTopic: zwave1/Lights_-_105/switch_binary/endpoint_2/targetValue/set
      transformationPattern:
        - JSONPATH:$.value
      "on": "true"
      "off": "false"

Two thoughts:

  1. Not sure if it right, but also not sure what it means either. My understanding is :$.value is meant to pull either a number or a string from the JSON and has worked flawlessly to date. Examples:

{“time”:1783617083164,“value”:26.3}

{“time”:1783615830584,“value”:false}

  1. Since it seems to have no impact, I think by OH logging standards should be debug

I think what it means is that your transformation won’t work, because : and possible $ has “special meaning” in YAML. For it to be forwarded literally, you must enclose it in double quotes:

If the “Code tab” produce this without quoting it, something is probably wrong with the Thing serialization - either that, or the warning is wrong.

@Lolodomo Do you know what is right here? Should it or should it not be quoted? Why isn’t the parser and the serializer in agreement?

Interesting ! Literally all my generic Mqtt channels (100+) transforms are without quotes.

They work fine, also the log messages were only [INFO ]

Quotes are only needed when characters with “special meaning” in YAML is contained within them, so that might be part of the equation.

One thing that is a bit strange here, is that transformationPattern is what seems to be a string array:

      transformationPattern:
        - JSONPATH:$.value
      "on": "true"
      "off": "false"

- in YAML means array. Normally, an array will contain key: value mappings, but this one doesn’t, so YAML must somehow “understand” that what it sees is in fact not a key, but a value. I think these parsing rules for YAML are really messy and prefer not to learn all the details, to spare myself the headache, but I would guess that this has something to do with it.

I don’t get why it’s an array though, but perhaps some transformations can take array arguments? If it were just a string pattern, not an array, it would look like this:

      transformationPattern: JSONPATH:$.value
      "on": "true"
      "off": "false"

In that case it might not need quotes, before the first : is “special” in that it separates the key from the value, while I don’t think subsequent :s matter. So, it is possible that what is parsed here is a key/value entry JSONPATH=$.value, but that probably isn’t the intention?

See explanation here

Yes, that part is “fine”, if it was a “user error”. But, from what I understand, this is code that was copied from the “Code tab”, which means that it was serialized that way. If that’s the case, then something is off. Why has it been serialized as an array?

I actually think there must be a bug here somewhere. This is where the log message originates:

It only expects to see BigDecimal if it’s not a string, so that’s the only thing it converts. It should at the very least, use toString() to convert it to a string, but it does not. So, it’s passed on as an array to the transformation. I have no idea what the consequence of that is.

So, the first bug is that

                } else if (valueIn != null) {
                  valueOut = valueIn.toString();

..is missing.

But, more interesting is perhaps how stringParameters is resolved. If the transformation works even if it’s sent as an array, and the serialization produces an array, maybe the parameter shouldn’t be in stringParameters at all.

Either that, or the serialization is wrong.

I see that the “requirement” for being classified as a stringParameter is that the config description is of type TEXT. The question is, how are arrays/lists provided? I think that they still use type TEXT, which makes the logic here fail.

As I suspected, this is the way MQTT defined the parameter:

    /**
     * transformation pattern for the availability payload
     */
    public List<String> transformationPattern = List.of();
			<parameter name="transformationPattern" type="text" multiple="true">
				<label>Availability Payload Transformations</label>
				<description>
					<![CDATA[
					Applies transformations to the incoming availability payload.
					A transformation example for a received JSON would be "JSONPATH:$.status" for
					a json {status: "Online"}.

					You can chain transformations by listing each transformation on a separate line, or
					by separating them with the intersection character ∩.
					]]>
				</description>
				<advanced>true</advanced>
			</parameter>

So, it is a List, which means that it ends up as an array in YAML. There definitely is a problem here, I’m not sure exactly where, but something isn’t right. I don’t remember if multiple in config description parameters means List/array, I thought maybe it meant comma separated string. But whatever the case is, something is wrong.

What is somewhat interesting in the linked example is that the transformation is in double quotes whereas mine are not. So, I understand the special character “-” is the cause. In my case I don’t understand how it got there. When I review the channel configuration there is no array character.

This is clear to me from reading the code. Basically, the assumption when the code was written, was that the only situation where you’d expect a string and get something else, is an unquoted number. Which is why it prints this “warning” and then tries to convert the number to a string value.

But, the assumption is wrong, there can be other situations. It could be a boolean as well for that matter, or it can be an array, or even an object/map. The logged text is just concerned with the one situation where it’s a number, so it thinks that the reason it isn’t deserialized as a string is that it wasn’t quoted. But, in fact, quotes has nothing to do with this. The reason it’s not a string is that it is a List, which leads to it printing this… quite meaningless message, and continues on without doing any conversion.

I think the fix is to rewrite the “check” so that it only prints the message if it’s a BigDecimal or BigInteger, and then just leaves it alone if it’s not.

Some of this is over my head, but the fix sounds ok. All on the logged messages were switches (the MQTT generic thing only contains switches, so there were no numbers involved. Values are true or false and converted to ON or OFF

for mqtt, transformationpattern is a list / array. You can give it a scalar string (not array), and openhab will normalize it into an array.

The array form is so that you no longer have to use the intersection symbol (but it’s still supported) to chain multiple transformations. Instead, just list the multiple transformations as individual array elements.

Yes, the problem is that the code in question doesn’t “know” about lists/arrays. I’ve written new code that handles it that I’m just about to test.

PR created: