Skip to content

[Regression v1.25.1] Template variable escaping with double braces broken #4606

@loompoor

Description

@loompoor

Description

The ADK documentation states that double braces ({{ and }}) should be used to escape literal curly braces in agent instructions, but the implementation in instructions_utils.py does not properly handle this escaping mechanism.
Expected Behavior

According to the State documentation:bypassing-state-injection:

🔴 Required Information

Describe the Bug:
The {{variable}} escaping syntax for literal curly braces in agent instruction strings was fixed in v1.25.0
(commit 7c7d25a). Version 1.25.1 re-introduces the regression — {{city}} and similar escaped patterns are
again matched by the {+[^{}]*}+ regex in instructions_utils.py and incorrectly treated as session state
variable lookups, causing a KeyError.

Steps to Reproduce:

  1. Install google-adk==1.25.1
  2. Create an agent with a string instruction containing {{city}} (a literal macro placeholder, not a session state variable):
  from google.adk.agents import LlmAgent
  
  agent = LlmAgent(
      name="test_agent",
      model="gemini-2.0-flash",
      instruction='Generate a keyword like "roofing cost in {{city}}".',
  )
  1. Run the agent via adk web or adk run and send any message

Expected Behavior:
{{city}} should be treated as a literal escaped brace and passed to the LLM as {city}, without attempting session state lookup. This worked correctly in v1.25.0.

Observed Behavior:

KeyError: 'Context variable not found: `city`.'
Traceback (most recent call last):
  File ".../google/adk/flows/llm_flows/instructions.py", line 56, in _process_agent_instruction
    si = await instructions_utils.inject_session_state(
  File ".../google/adk/utils/instructions_utils.py", line 124, in inject_session_state
    return await _async_sub(r'{+[^{}]*}+', _replace_match, template)
  File ".../google/adk/utils/instructions_utils.py", line 75, in _async_sub
    replacement = await repl_async_fn(match)
  File ".../google/adk/utils/instructions_utils.py", line 122, in _replace_match
    raise KeyError(f'Context variable not found: `{var_name}`.')

Environment Details:

  • ADK Library Version (pip show google-adk): google-adk==1.25.1
  • Desktop OS: macOS
  • Python Version (python -V): 3.13.12

Model Information:

  • Are you using LiteLLM: No
  • Which model is being used: N/A

🟡 Optional Information

Providing this information greatly speeds up the resolution process.

Regression:
Yes. This worked correctly in google-adk==1.25.0. The fix was introduced in commit 7c7d25a (closing issue #3527), but the regression was re-introduced in v1.25.1.

Logs:

2026-02-24 16:56:30,862 - ERROR - adk_web_server.py:1629 - Error in event_generator: 'Context variable not found: `city`.'
KeyError: 'Context variable not found: `city`.'
  File ".../google/adk/utils/instructions_utils.py", line 122, in _replace_match
    raise KeyError(f'Context variable not found: `{var_name}`.')

Screenshots / Video:
If applicable, add screenshots or screen recordings to help explain
your problem.

Additional Context:
The workaround is to pass a callable (InstructionProvider) instead of a string to the instruction parameter, which bypasses inject_session_state entirely:

Minimal Reproduction Code:
Please provide a code snippet or a link to a Gist/repo that isolates the issue.

from google.adk.agents import Agent

# This raises KeyError on v1.25.1, works on v1.25.0
agent = Agent(
    name="test_agent",
    model="gemini-2.0-flash",
    instruction='Generate a keyword like "roofing cost in {{city}}".',
)

How often has this issue occurred?:

  • Always (100%)

Metadata

Metadata

Assignees

No one assigned

    Labels

    core[Component] This issue is related to the core interface and implementation

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions