ADK State asking for async

I am trying to understand why the agent keeps asking for an async runner, but when I change to async, I get into an infinite bug loop. He is the code:

“”"
Test state namespaces to see persistence differences
Run with: python test_namespaces.py
“”"

from agent import root_agent
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.genai.types import Content, Part

Setup

session_service = InMemorySessionService()
session = session_service.create_session(
app_name=“namespace_demo_app”,
user_id=“user1”,
session_id=“session1”
)

runner = Runner(
agent=root_agent,
app_name=“namespace_demo_app”,
session_service=session_service
)

Set all four namespace types

print(“=== Setting state in all namespaces ===”)
session.state[“app:name”] = “Namespace Demo”
session.state[“app:version”] = “2.0”
session.state[“user:theme”] = “dark”
session.state[“topic”] = “state management”
session.state[“temp:step”] = “initialization”

print(f"State before run: {session.state}\n")

Run agent

print(“=== Running agent (Turn 1) ===”)
result = runner.run(
user_id=“user1”,
session_id=“session1”,
new_message=Content(parts=[Part(text=“Show me the namespace values”)])
)

Show response

for event in result:
if event.is_final_response():
print(f"Agent response:\n{event.content.parts[0].text}\n")

Check state after turn

print(“=== State after Turn 1 ===”)
print(f"Full state: {session.state}“)
print(f"temp:step: {session.state.get(‘temp:step’)}”) # Should be GONE
print(f"topic: {session.state.get(‘topic’)}“) # Should persist
print(f"user:theme: {session.state.get(‘user:theme’)}”) # Should persist
print(f"app:version: {session.state.get(‘app:version’)}") # Should persist

print(“\n=== Simulating Turn 2 (same session) ===”)
result2 = runner.run(
user_id=“user1”,
session_id=“session1”,
new_message=Content(parts=[Part(text=“Check state again”)])
)

for event in result2:
if event.is_final_response():
print(f"Agent response:\n{event.content.parts[0].text}\n")

print(“=== State after Turn 2 ===”)
print(f"Full state: {session.state}“)
print(f"temp:step: {session.state.get(‘temp:step’)}”) # Still GONE
print(f"topic: {session.state.get(‘topic’)}“) # Still here (session state)
print(f"user:theme: {session.state.get(‘user:theme’)}”) # Still here (user state)

Simulate new session

print(“\n=== Simulating NEW Session (session2) ===”)
session2 = session_service.create_session(
app_name=“namespace_demo_app”,
user_id=“user1”, # Same user
session_id=“session2” # Different session
)

print(f"New session state: {session2.state}“)
print(f"topic: {session2.state.get(‘topic’)}”) # Should be GONE (session-scoped)
print(f"user:theme: {session2.state.get(‘user:theme’)}“) # Should PERSIST (user-scoped)
print(f"app:version: {session2.state.get(‘app:version’)}”) # Should PERSIST (app-scoped)

Here is the console log, when I test the code (without async)

Console log error.

(.venv) C:\Users\Túlio\Documents\GitHub\adk-workspace>python personalized_greeter\test_templating.py
=== Test 1: No state (all defaults) ===
Exception in thread Thread-1 (_asyncio_thread_main):
Traceback (most recent call last):
File “C:\Python314\Lib\threading.py”, line 1081, in _bootstrap_inner
self._context.run(self.run)
~~~~~~~~~~~~~~~~~^^^^^^^^^^
File “C:\Python314\Lib\threading.py”, line 1023, in run
self._target(self._args, **self._kwargs)
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\runners.py”, line 435, in _asyncio_thread_main
asyncio.run(_invoke_run_async())
~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
File “C:\Python314\Lib\asyncio\runners.py”, line 204, in run
return runner.run(main)
~~~~~~~~~~^^^^^^
File “C:\Python314\Lib\asyncio\runners.py”, line 127, in run
return self._loop.run_until_complete(task)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File “C:\Python314\Lib\asyncio\base_events.py”, line 719, in run_until_complete
return future.result()
~~~~~~~~~~~~~^^
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\runners.py”, line 428, in _invoke_run_async
async for event in agen:
event_queue.put(event)
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\runners.py”, line 561, in run_async
async for event in agen:
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\runners.py”, line 549, in _run_with_trace
async for event in agen:
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\runners.py”, line 778, in _exec_with_plugin
async for event in agen:
…<64 lines>…
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\runners.py”, line 538, in execute
async for event in agen:
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\agents\base_agent.py”, line 294, in run_async
async for event in agen:
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\agents\llm_agent.py”, line 468, in _run_async_impl
async for event in agen:
…<5 lines>…
should_pause = True
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\flows\llm_flows\base_llm_flow.py”, line 427, in run_async
async for event in agen:
last_event = event
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\flows\llm_flows\base_llm_flow.py”, line 446, in _run_one_step_async
async for event in agen:
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\flows\llm_flows\base_llm_flow.py”, line 535, in _preprocess_async
async for event in agen:
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\flows\llm_flows\instructions.py”, line 129, in run_async
await _build_instructions(invocation_context, llm_request)
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\flows\llm_flows\instructions.py”, line 110, in _build_instructions
si = await _process_agent_instruction(agent, invocation_context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\flows\llm_flows\instructions.py”, line 56, in _process_agent_instruction
si = await instructions_utils.inject_session_state(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
raw_si, ReadonlyContext(invocation_context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\utils\instructions_utils.py”, line 124, in inject_session_state
return await _async_sub(r’{+[^{}]
}+‘, _replace_match, template)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\utils\instructions_utils.py”, line 75, in _async_sub
replacement = await repl_async_fn(match)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\utils\instructions_utils.py”, line 122, in _replace_match
raise KeyError(f’Context variable not found: {var_name}.’)
KeyError: ‘Context variable not found: membership_tier.’
=== Test 2: With user name ===
Exception in thread Thread-2 (_asyncio_thread_main):
Traceback (most recent call last):
File “C:\Python314\Lib\threading.py”, line 1081, in _bootstrap_inner
self._context.run(self.run)
~~~~~~~~~~~~~~~~~^^^^^^^^^^
File “C:\Python314\Lib\threading.py”, line 1023, in run
self._target(self._args, **self._kwargs)
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\runners.py”, line 435, in _asyncio_thread_main
asyncio.run(_invoke_run_async())
~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
File “C:\Python314\Lib\asyncio\runners.py”, line 204, in run
return runner.run(main)
~~~~~~~~~~^^^^^^
File “C:\Python314\Lib\asyncio\runners.py”, line 127, in run
return self._loop.run_until_complete(task)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File “C:\Python314\Lib\asyncio\base_events.py”, line 719, in run_until_complete
return future.result()
~~~~~~~~~~~~~^^
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\runners.py”, line 428, in _invoke_run_async
async for event in agen:
event_queue.put(event)
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\runners.py”, line 561, in run_async
async for event in agen:
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\runners.py”, line 549, in _run_with_trace
async for event in agen:
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\runners.py”, line 778, in _exec_with_plugin
async for event in agen:
…<64 lines>…
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\runners.py”, line 538, in execute
async for event in agen:
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\agents\base_agent.py”, line 294, in run_async
async for event in agen:
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\agents\llm_agent.py”, line 468, in _run_async_impl
async for event in agen:
…<5 lines>…
should_pause = True
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\flows\llm_flows\base_llm_flow.py”, line 427, in run_async
async for event in agen:
last_event = event
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\flows\llm_flows\base_llm_flow.py”, line 446, in _run_one_step_async
async for event in agen:
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\flows\llm_flows\base_llm_flow.py”, line 535, in _preprocess_async
async for event in agen:
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\flows\llm_flows\instructions.py”, line 129, in run_async
await _build_instructions(invocation_context, llm_request)
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\flows\llm_flows\instructions.py”, line 110, in _build_instructions
si = await _process_agent_instruction(agent, invocation_context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\flows\llm_flows\instructions.py”, line 56, in _process_agent_instruction
si = await instructions_utils.inject_session_state(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
raw_si, ReadonlyContext(invocation_context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\utils\instructions_utils.py”, line 124, in inject_session_state
return await _async_sub(r’{+[^{}]
}+‘, _replace_match, template)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\utils\instructions_utils.py”, line 75, in _async_sub
replacement = await repl_async_fn(match)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\utils\instructions_utils.py”, line 122, in _replace_match
raise KeyError(f’Context variable not found: {var_name}.’)
KeyError: ‘Context variable not found: membership_tier.’
=== Test 3: With all state values ===
Exception in thread Thread-3 (_asyncio_thread_main):
Traceback (most recent call last):
File “C:\Python314\Lib\threading.py”, line 1081, in _bootstrap_inner
self._context.run(self.run)
~~~~~~~~~~~~~~~~~^^^^^^^^^^
File “C:\Python314\Lib\threading.py”, line 1023, in run
self._target(self._args, **self._kwargs)
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\runners.py”, line 435, in _asyncio_thread_main
asyncio.run(_invoke_run_async())
~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
File “C:\Python314\Lib\asyncio\runners.py”, line 204, in run
return runner.run(main)
~~~~~~~~~~^^^^^^
File “C:\Python314\Lib\asyncio\runners.py”, line 127, in run
return self._loop.run_until_complete(task)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^
File “C:\Python314\Lib\asyncio\base_events.py”, line 719, in run_until_complete
return future.result()
~~~~~~~~~~~~~^^
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\runners.py”, line 428, in _invoke_run_async
async for event in agen:
event_queue.put(event)
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\runners.py”, line 561, in run_async
async for event in agen:
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\runners.py”, line 549, in _run_with_trace
async for event in agen:
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\runners.py”, line 778, in _exec_with_plugin
async for event in agen:
…<64 lines>…
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\runners.py”, line 538, in execute
async for event in agen:
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\agents\base_agent.py”, line 294, in run_async
async for event in agen:
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\agents\llm_agent.py”, line 468, in _run_async_impl
async for event in agen:
…<5 lines>…
should_pause = True
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\flows\llm_flows\base_llm_flow.py”, line 427, in run_async
async for event in agen:
last_event = event
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\flows\llm_flows\base_llm_flow.py”, line 446, in _run_one_step_async
async for event in agen:
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\flows\llm_flows\base_llm_flow.py”, line 535, in _preprocess_async
async for event in agen:
yield event
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\flows\llm_flows\instructions.py”, line 129, in run_async
await _build_instructions(invocation_context, llm_request)
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\flows\llm_flows\instructions.py”, line 110, in _build_instructions
si = await _process_agent_instruction(agent, invocation_context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\flows\llm_flows\instructions.py”, line 56, in _process_agent_instruction
si = await instructions_utils.inject_session_state(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
raw_si, ReadonlyContext(invocation_context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\utils\instructions_utils.py”, line 124, in inject_session_state
return await _async_sub(r’{+[^{}]
}+‘, _replace_match, template)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\utils\instructions_utils.py”, line 75, in _async_sub
replacement = await repl_async_fn(match)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File “C:\Users\Túlio\Documents\GitHub\adk-workspace.venv\Lib\site-packages\google\adk\utils\instructions_utils.py”, line 122, in _replace_match
raise KeyError(f’Context variable not found: {var_name}.’)
KeyError: ‘Context variable not found: membership_tier.’
=== Current state ===
{‘user_name’: ‘Alex’, ‘user_language’: ‘Spanish’, ‘membership_tier’: ‘Premium’}

(.venv) C:\Users\Túlio\Documents\GitHub\adk-workspace>