Afterward, when I tried to retrieve the value for context.getVariable('variableName.header'), it wasn’t defined, even though context.getVariable('variableName') was.
Is this a bug, or has it always worked this way?
PS
Tried it in the local emulator with latest Cloud Code extension in vscode
That behaviour actually makes sense once you look at how Apigee stores variables internally. Under the hood it doesn’t keep them in a flat key-value map, but in a kind of hierarchical tree structure where every variable name split by dots represents a path in that tree.
So when you do something like setVariable('foo.bar', 'value'), Apigee will first check whether there’s already a node called foo. If there isn’t, it’ll create a new “branch” node and then hang bar under it. But if you’ve previously assigned a simple value directly to foo, then that name is now a leaf (scalar value) and it can’t also become a branch with children beneath it.
In other words, a variable can be either a single value or a container for other sub-variables, but not both at the same time. When you later try to write to foo.bar, Apigee sees that foo already holds a plain value and silently drops the attempt. That’s why you can still read back foo, but foo.bar comes back undefined.
I don’t think it’s bug, but just how the internal tree works, still, it can be confusing when you first bump into it. The safe rule of thumb is: if you ever plan to use dotted names, treat them the same way as request/response flow variables - don’t assign a direct value to the parent - keep it as a “branch” in that variable tree.
Here’s a quick screenshot to illustrate it - both variableName.header1 and variableName.header2 resolve correctly because the parent variableName itself was never set to a scalar value.
This isn’t a bug — it’s expected behavior. In Apigee, the dot (.) in a variable name is treated as a property separator, not as part of the variable name itself. So when you use variableName.header, Apigee interprets it as a sub-property of variableName, not a new variable. You can avoid this by using underscores or another separator instead of dots.
Thank you both for the excellent explanation.
I looked through the Apigee docs but couldn’t find an explanation for this specific behaviour. I really think this should be added right at the top of the JS policy because it took me quite a bit of time to figure out. I’m posting this here so others can find the same information more easily.