-
Notifications
You must be signed in to change notification settings - Fork 2k
Description
** Please make sure you read the contribution guide and file the issues in the right place. **
Contribution guide.
Describe the bug
Creating a session twice with the same id for the same user returns an internal server error when using a DatabaseSessionService
.
To Reproduce
Start an ADK server. Here's a minimal example:
import os
import uvicorn
from dotenv import find_dotenv, load_dotenv
from fastapi import FastAPI
from google.adk.cli.fast_api import get_fast_api_app
load_dotenv(find_dotenv())
# --- Configuration ---
AGENT_DIR = os.path.dirname(os.path.abspath(__file__))
SESSION_SERVICE_URI = (
f"postgresql://{os.getenv('DB_USERNAME')}:{os.getenv('DB_PASSWORD')}@"
f"{os.getenv('DB_HOST')}:{os.getenv('DB_PORT')}/{os.getenv('DB_NAME')}"
)
# --- Set up the FastAPI application ---
app: FastAPI = get_fast_api_app(
agents_dir=AGENT_DIR,
session_service_uri=SESSION_SERVICE_URI,
web=True,
)
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8081)
And a very simple agent:
import os
from google.adk import Agent
AGENT_NAME = "hello_world_agent"
root_agent = Agent(
name=AGENT_NAME,
model=os.getenv("MODEL_AGENT"),
instruction="Just say hello back to the user.",
)
Supposing the database is correctly set up, creating a session can be done like this:
curl -X POST "http://localhost:8081/apps/hello_world_agent/users/user/sessions" -H "Content-Type: application/json" -d '{"session_id": "test-123"}'
When sending the same request again, I would expect the server to have the same behavior as when using the InMemorySessionService
, but it is not the case. Instead, an error is thrown:
INFO: 127.0.0.1:61218 - "POST /apps/hello_world_agent/users/user/sessions HTTP/1.1" 500 Internal Server Error
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 1967, in _exec_single_context
self.dialect.do_execute(
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/engine/default.py", line 951, in do_execute
cursor.execute(statement, parameters)
psycopg2.errors.UniqueViolation: duplicate key value violates unique constraint "sessions_pkey"
DETAIL: Key (app_name, user_id, id)=(hello_world_agent, user, test-123) already exists.
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/uvicorn/protocols/http/h11_impl.py", line 403, in run_asgi
result = await app( # type: ignore[func-returns-value]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__
return await self.app(scope, receive, send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/fastapi/applications.py", line 1054, in __call__
await super().__call__(scope, receive, send)
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/starlette/applications.py", line 113, in __call__
await self.middleware_stack(scope, receive, send)
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 186, in __call__
raise exc
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 164, in __call__
await self.app(scope, receive, _send)
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 63, in __call__
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
raise exc
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/starlette/routing.py", line 716, in __call__
await self.middleware_stack(scope, receive, send)
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/starlette/routing.py", line 736, in app
await route.handle(scope, receive, send)
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/starlette/routing.py", line 290, in handle
await self.app(scope, receive, send)
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/starlette/routing.py", line 78, in app
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 53, in wrapped_app
raise exc
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/starlette/_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/starlette/routing.py", line 75, in app
response = await f(request)
^^^^^^^^^^^^^^^^
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/fastapi/routing.py", line 302, in app
raw_response = await run_endpoint_function(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/fastapi/routing.py", line 213, in run_endpoint_function
return await dependant.call(**values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/google/adk/cli/adk_web_server.py", line 524, in create_session
session = await self.session_service.create_session(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/google/adk/sessions/database_session_service.py", line 488, in create_session
sql_session.commit()
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 2032, in commit
trans.commit(_to_root=True)
File "<string>", line 2, in commit
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/orm/state_changes.py", line 137, in _go
ret_value = fn(self, *arg, **kw)
^^^^^^^^^^^^^^^^^^^^
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 1313, in commit
self._prepare_impl()
File "<string>", line 2, in _prepare_impl
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/orm/state_changes.py", line 137, in _go
ret_value = fn(self, *arg, **kw)
^^^^^^^^^^^^^^^^^^^^
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 1288, in _prepare_impl
self.session.flush()
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 4345, in flush
self._flush(objects)
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 4480, in _flush
with util.safe_reraise():
^^^^^^^^^^^^^^^^^^^
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/util/langhelpers.py", line 224, in __exit__
raise exc_value.with_traceback(exc_tb)
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/orm/session.py", line 4441, in _flush
flush_context.execute()
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/orm/unitofwork.py", line 466, in execute
rec.execute(self)
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/orm/unitofwork.py", line 642, in execute
util.preloaded.orm_persistence.save_obj(
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/orm/persistence.py", line 93, in save_obj
_emit_insert_statements(
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/orm/persistence.py", line 1233, in _emit_insert_statements
result = connection.execute(
^^^^^^^^^^^^^^^^^^^
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 1419, in execute
return meth(
^^^^^
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/sql/elements.py", line 526, in _execute_on_connection
return connection._execute_clauseelement(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 1641, in _execute_clauseelement
ret = self._execute_context(
^^^^^^^^^^^^^^^^^^^^^^
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 1846, in _execute_context
return self._exec_single_context(
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 1986, in _exec_single_context
self._handle_dbapi_exception(
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 2355, in _handle_dbapi_exception
raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/engine/base.py", line 1967, in _exec_single_context
self.dialect.do_execute(
File "/Users/user/LocalProjects/agent_project/adk/.venv/lib/python3.12/site-packages/sqlalchemy/engine/default.py", line 951, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.IntegrityError: (psycopg2.errors.UniqueViolation) duplicate key value violates unique constraint "sessions_pkey"
DETAIL: Key (app_name, user_id, id)=(hello_world_agent, user, test-123) already exists.
[SQL: INSERT INTO sessions (app_name, user_id, id, state, create_time, update_time) VALUES (%(app_name)s, %(user_id)s, %(id)s, %(state)s::JSONB, now(), now()) RETURNING sessions.create_time, sessions.update_time]
[parameters: {'app_name': 'hello_world_agent', 'user_id': 'user', 'id': 'test-123', 'state': '{}'}]
(Background on this error at: https://sqlalche.me/e/20/gkpj)
Expected behavior
Just like when using the InMemorySessionService
, no error should be thrown.
Desktop (please complete the following information):
- OS: macOS
- Python version(python -V): 3.12.9
- ADK version(pip show google-adk): 1.14.0
Model Information:
- Are you using LiteLLM: No
- Which model is being used: gemini-2.5