OK, in my rush to get you an answer as I was shutting down for the night, I missed that previous lines *also* had @{selected} syntax.
Basically, *everywhere* you have that (and I am drawing a distinction between that syntax and Fetch syntax, which we'll get to in a minute), it will be one of the first things to resolve -- even before your query.
So where you have it in your ChatSetAttr line you do not need to escape it:
!modattr --silent --name @{selected|token_name} --repeating_resource_$0_resource_left|-1
(Note that the later pipe IS escaped because that isn't part of @{selected} syntax... that's part of what ChatSetAttr needs.)
Also, I see another @{selected} reference at the end of the template line in the ZeroFrame batch set. This should be provided EITHER as a normal Roll20 syntax structure without HTML substitutions:
@{selected|token_name}
...OR... it should be rendered as a Fetch construction:
@(selected.token_name)
The Fetch construction *could* be deferred, if you want, but in this case it won't matter... the same token will look like the selected token at both opportunities Fetch has to resolve.
To put a fine point on that (feel free to skip; just presenting this in case you're curious and want to learn), the order of operations will look like:
- Roll20 attribute constructions resolve (like @{selected} constructions)
- Your query will resolve
- Inline rolls will resolve
- The /em line is sent to chat
- The ChatSetAttr and Roll20AM commands are sent to the Script Moderator (sandbox) (metascripts have opportunities to work in these lines, if necessary)
- The line starting the ZeroFrame batch command is sent to the Script Moderator
- Zeroing in on that message, the metascripts start looping...
- ...Fetch will resolve any constructions it sees (this is the first opportunity; at this point, the selected token of the message is STILL the selected token)
- ...ZeroFrame will un-defer and dispatch the batch commands individually
- The whisper command (at the end of the command) is sent to chat
- THEN the individual commands previously dispatched by ZeroFrame are caught by the Script Moderator
- Zeroing in on these, the metascripts start looping...
- ....since it is a batch-dispatched message, ZeroFrame catches each and restores key information like selected tokens
- ...Fetch will resolve any constructions it sees (this is the second opportunity; at this point, the selected token of the message has been restored to what it always was)
Hopefully I haven't missed further @{selected} syntax in your command, but you'll have it in other commands referenced in your overall query, too, so for your ability to do it yourself (in either case) I wanted to explain *why* I was saying to make the changes I'm pointing out. That way you'll know which ones need to change for the future.
One Point About Queries...
You mention that the HTML-substituted line no longer works through chat... this is how it is. Once you encode a character with its HTML replacement, you really need an opportunity for the character to decode back in order for the command to work. A query gives you this opportunity, so typically when you encode/substitute a line like this, you are ONLY intending to use it through/via a query.
There is an alternative, however.
If you saved each of your commands as non-substituted lines in their own abilities on a character sheet (probably a mule character sheet), or as individual macros, then you could still run your query, but use Fetch constructions to retrieve them:
?{Pick command package|Lesser Potion,@(MuleCharacter.Lesser)|Greater Potion,@(MuleCharacter.Greater)|...
Because queries resolve *before* metascripts get involved, those Fetch references to abilities on your mule character won't expand to muddy up your syntax... that means they on longer require HTML substitution. HOWEVER, they will require using ALL Fetch references (instead of @{selected} Roll20 syntax) since your opportunity for resolving *those* formations will have passed before your query resolves (remember, the order of operations has attributes resolving before queries resolve). So change your @{selected} references to be @(selected) references.
Now your individual commands will still work as standalone commands (without having to use the query), but your query will ALSO work (and the syntax will be much cleaner).
One Other Thing...
I don't think you can whisper to a token (as you do in your last line). This is working because every token you run this command on is probably sharing a name with the character it represents, so by the time Roll20 sees the /w command, the recipient is designated as something it recognizes (and knows how to send a message to). Just pointing this out in case you would ever try to run this command with a token that did NOT share a name with its character (obviously running this command with a token that didn't represent a character will throw other errors since you are attempting to modify things on what would be a non-existent character sheet, at that point). You might be better off to change the last whisper recipient to be a character_name reference instead of the token_name you have now.