# Format String - "Unknown engine "template" while parsing selector"

**URL:** <https://forum.robotframework.org/t/format-string-unknown-engine-template-while-parsing-selector/8263>\
**Category:** Robot Framework\
**Created:** [9 January 2025 15:10 UTC](https://forum.robotframework.org/t/format-string-unknown-engine-template-while-parsing-selector/8263 "2025-01-09T15:10:27Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![JST81](https://avatars.discourse-cdn.com/v4/letter/j/b77776/32.png) [@JST81](https://forum.robotframework.org/u/JST81)\
**Post date:** [9 January 2025 15:10 UTC](https://forum.robotframework.org/t/format-string-unknown-engine-template-while-parsing-selector/8263/1 "2025-01-09T15:10:27Z")

</div>

Hello, I recently upgraded RF from 7.0.1 to 7.1 and noticed a difference regarding how selectors/locators are being put together in my test cases.

For instance, part of a test would look like this:  
${timeSelector} Format String template=${variable X} beginTime=${beginTime}  
Click selector=${timeSelector}

In this case, ${variableX} would be defined elsewhere as “css=ul[id\*=‘P2020\_BEGINTIME\_HIDDEN’] div[aria-label=‘{beginTime}’]”

This used to work perfectly, but since upgrading to 7.1 I get errors like “Unknown engine “template” while parsing selector”. The solution for me is to remove the ‘template=’ part and then it works again. But I don’t understand why this happens. In the release notes of RF 7.1 something is mentioned about _“Format String: Allow using template strings containing = without escaping”_ so I guess it has something to do with this. Can someone explain why the old syntax of using ‘template=${variable X}’ no longer works in this case and how I should go about this? Thanks.

---

<div class="post-metadata">

**Author:** ![damies13](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.robotframework.org/damies13/32/623_2.png) [@damies13](https://forum.robotframework.org/u/damies13)\
**Post date:** [9 January 2025 15:52 UTC](https://forum.robotframework.org/t/format-string-unknown-engine-template-while-parsing-selector/8263/2 "2025-01-09T15:52:39Z")

</div>

Hi John,

Is the `Format String` keyword a keyword you created? it might pay to show that keyword, as that might give a clue as to what the problem is?

Also a tip: _use use 3 backticks (```) before and after your robot code, so the formatting is preserved_

Dave.

---

<div class="post-metadata">

**Author:** ![JST81](https://avatars.discourse-cdn.com/v4/letter/j/b77776/32.png) [@JST81](https://forum.robotframework.org/u/JST81)\
**Post date:** [9 January 2025 19:28 UTC](https://forum.robotframework.org/t/format-string-unknown-engine-template-while-parsing-selector/8263/3 "2025-01-09T19:28:45Z")

</div>

Hello Dave, `Format String` is a keyword from the String Library ([https://robotframework.org/robotframework/latest/libraries/String.html#Format%20String](https://robotframework.org/robotframework/latest/libraries/String.html#Format%20String)).

I’ll repost the code snippet below in a better format:

`${timeSelector} Format String template=${variable X} beginTime=${beginTime}`  
`Click selector=${timeSelector}`

with  
`${variable X} = "css=ul[id*='P2010_BEGINTIME_HIDDEN'] div[aria-label='{beginTime}']"`

This results in

> Error: locator.click: Unknown engine “template” while parsing selector template=css=ul[id\*=‘P2010\_BEGINTIME\_HIDDEN’] div[aria-label=‘11:45’]
> 
> Call log:
> 
> - waiting for locator(‘iframe[title='Manage hours']’).contentFrame().locator(‘template=css=ul[id\*='P2010\_BEGINTIME\_HIDDEN'] div[aria-label='11:45']’)

So it seems the word ‘template’ now made its way into the locator url itself. In version 7.0.1 this used to work fine, but no longer in version 7.1. If I remove the ‘template=’ from the code like this, it works:

`${timeSelector} Format String ${variable X} beginTime=${beginTime}`  
`Click selector=${timeSelector}`

But I would like to understand what happens here 🙂 .

---

<div class="post-metadata">

**Author:** ![rasjani](https://avatars.discourse-cdn.com/v4/letter/r/858c86/32.png) [@rasjani](https://forum.robotframework.org/u/rasjani)\
**Post date:** [9 January 2025 20:32 UTC](https://forum.robotframework.org/t/format-string-unknown-engine-template-while-parsing-selector/8263/4 "2025-01-09T20:32:40Z")

</div>

> <https://github.com/robotframework/robotframework/issues/4821>
>
> The Format String keyword from BuiltIn String Library needs escaping of equals s…ign (=). Is this behaviour expected?
> 
> \_Robot Framework REPL\_
> \`\`\`
> \>\>\> Format String \[text()="{}"\] TESTING
> ERROR Keyword 'String.Format String' got positional argument after named arguments.
> \>\>\>
> \>\>\> Format String \[text()\\="{}"\] TESTING
> \[text()="TESTING"\]
> \`\`\`
> \_Python REPL\_
> \`\`\`
> \>\>\> '\[text()="{}"\]'.format('TESTING')
> '\[text()="TESTING"\]'
> \>\>\>
> \`\`\`

Looks like it was a bug fix

---

<div class="post-metadata">

**Author:** ![JST81](https://avatars.discourse-cdn.com/v4/letter/j/b77776/32.png) [@JST81](https://forum.robotframework.org/u/JST81)\
**Post date:** [9 January 2025 21:00 UTC](https://forum.robotframework.org/t/format-string-unknown-engine-template-while-parsing-selector/8263/5 "2025-01-09T21:00:12Z")

</div>

Yes, that is what I found out in the release notes. But I don’t really get what that changed for my existing code. It seems I cannot use ‘template=’ anymore, but to be honest I also don’t know why that was used in my code in the first place (it was made by someone else). I only know it worked before and now it doesn’t, unless I remove the ‘template=’ part. So why do I have to change the syntax on my end for this to work again? I would like to understand 🙂

---

<div class="post-metadata">

**Author:** ![rasjani](https://avatars.discourse-cdn.com/v4/letter/r/858c86/32.png) [@rasjani](https://forum.robotframework.org/u/rasjani)\
**Post date:** [9 January 2025 23:04 UTC](https://forum.robotframework.org/t/format-string-unknown-engine-template-while-parsing-selector/8263/6 "2025-01-09T23:04:59Z")

</div>

Didnt read check the patch but but afaik, your code worked by “accident”. `template` was not named argument eg, kwarg in python but because of how robot worked before the change and it saw there was = to be passed into keyword, it was considered to be named argument while it was not.

---

<div class="post-metadata">

**Author:** ![pekkaklarck](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.robotframework.org/pekkaklarck/32/1019_2.png) [@pekkaklarck](https://forum.robotframework.org/u/pekkaklarck)\
**Post date:** [15 January 2025 00:26 UTC](https://forum.robotframework.org/t/format-string-unknown-engine-template-while-parsing-selector/8263/7 "2025-01-15T00:26:28Z")

</div>

Yeah, this is caused by the aforementioned fix. I’ll explain why the fix affects this usage below.

1. The keyword signature used to be `format_string(template, *positional, **named)`. The `template` argument was a normal argument that could be used both as a positional argument like `Format String the template` and as a named argument like `Format String template=the template`.
2. Because the keyword accepted free named-arguments (`**named`), any argument with an equal sign was considered a named argument. Thus if the template contained `=` like in `Format String some=content`, it was considered to be a named argument `some` with a value `content`.
3. A workaround was escaping the equal sign like `Format Sting some\=content`. It worked but not everyone knew about escaping and it was somewhat annoying in general.
4. To avoid the need for escaping, the signature was changed to `format_string(template, /, *positional, **named)`. The `/` in the signature makes `template` a positional-only argument that can be used only like `Format String the template`. Using it like `Format String template=the template` isn’t an error, but it is considered to mean that your template is the literal value `template=the template`.

It’s unfortunate that the fix causes this problem, but I still consider it more important that you don’t need to escape possible equal signs that you cannot use the `template=` prefix. Luckily the version without the prefix works also with older Robot versions, so you can simply remove it.
