Session.State().Get/Set do not appear to work
I tried the following basic get/set with both in-memory and database, neither work as expected and have the same output, notably they both show the state value just after being set, but it never seems to retain after the function return
[!CAUTION] none of the state prefixes appear to work
Not sure if I'm doing something wrong, or there is a copy in the implementation which means this never makes it back to storage...?
func sessionGetState(r *runtime.Runtime, c *runtime.Client, m *runtime.Message) {
var s StatePayload
if err := json.Unmarshal(m.Payload, &s); err != nil {
log.Printf("Error unmarshaling 'session.getState' payload: %v", err)
return
}
// lookup session
resp, err := r.S.Get(r.Ctx, &session.GetRequest{
AppName: r.AppName,
UserID: c.User,
SessionID: s.Sid,
})
if err != nil {
...
}
v, err := resp.Session.State().Get(s.Key)
if err != nil {
...
}
s.Val = v
// fmt.Println("mailing sessions", payload)
c.Mail("session.getState.resp", s)
}
func sessionPutState(r *runtime.Runtime, c *runtime.Client, m *runtime.Message) {
var s StatePayload
if err := json.Unmarshal(m.Payload, &s); err != nil {
log.Printf("Error unmarshaling 'session.getState' payload: %v", err)
return
}
// lookup session
resp, err := r.S.Get(r.Ctx, &session.GetRequest{
AppName: r.AppName,
UserID: c.User,
SessionID: s.Sid,
})
if err != nil {
...
}
err = resp.Session.State().Set(s.Key, s.Val)
if err != nil {
...
}
fmt.Println("session.state", maps.Collect(resp.Session.State().All()))
}
Received message type: session.state.put
sessionPutState {28b3c4f4-d140-4409-ad0c-56336ad4971c title testing}
State Set 28b3c4f4-d140-4409-ad0c-56336ad4971c title testing
session.state map[title:testing]
Received message type: session.get
sessionGet {"id":"28b3c4f4-d140-4409-ad0c-56336ad4971c"}
Received message type: session.state.put
sessionPutState {28b3c4f4-d140-4409-ad0c-56336ad4971c foo bar}
State Set 28b3c4f4-d140-4409-ad0c-56336ad4971c foo bar
session.state map[foo:bar]
Received message type: session.state.get
Error: session.getState.getState: state key does not exist
Received message type: session.state.put
sessionPutState {28b3c4f4-d140-4409-ad0c-56336ad4971c user:name verdverm}
State Set 28b3c4f4-d140-4409-ad0c-56336ad4971c user:name verdverm
session.state map[user:name:verdverm]
Received message type: session.state.get
Error: session.getState.getState: state key does not exist
@verdverm Seems that you're updating the state in the copied memory session. Guess you should use the Create API to update the updated session back to the session service.
Create would be a bad name for something that updates a session, Put or Set would be more appropriate, like the State interface. Either way, it doesn't seem to work or is overwriting it again before I can inspect
025/11/19 22:10:52 /Users/tony/go/pkg/mod/google.golang.org/[email protected]/session/database/service.go:124 UNIQUE constraint failed: sessions.app_name, sessions.user_id, sessions.id
[0.191ms] [rows:0] INSERT INTO `sessions` (`app_name`,`user_id`,`id`,`state`,`create_time`,`update_time`) VALUES ("veg","tony","2f0e9fe1-68b1-496b-bdf7-b3958dded320","{""hello"":""world""}","2025-11-19 22:10:52.819","2025-11-19 22:10:52.819")
State Set 2f0e9fe1-68b1-496b-bdf7-b3958dded320 hello world
session.state map[hello:world]
^Csignal: interrupt
FAIL
tony@hydrogen: ~/hof/hof _next!
$ sqlite3 veg.db [22:10:58]
SQLite version 3.43.2 2023-10-10 13:08:14
Enter ".help" for usage hints.
sqlite> select * from sessions;
veg|tony|5937ffcc-17db-4fbd-909e-e73919cc5cff|{}|2025-11-19 02:41:25.009195-08:00|2025-11-19 05:25:01.075054-08:00
veg|tony|8be7815a-1188-4732-ad42-fb600cc2360e|{}|2025-11-19 21:42:56.80102-08:00|2025-11-19 21:44:43.776355-08:00
veg|tony|2f0e9fe1-68b1-496b-bdf7-b3958dded320|{}|2025-11-19 22:07:14.963185-08:00|2025-11-19 22:07:14.963185-08:00
sqlite>
[!IMPORTANT] manually running the same SQL uncovers the error
sqlite> INSERT INTO `sessions` (`app_name`,`user_id`,`id`,`state`,`create_time`,`update_time`) VALUES ("veg","tony","2f0e9fe1-68b1-496b-bdf7-b3958dded320","{""hello"":""world""}","2025-11-19 22:10:52.819","2025-11-19 22:10:52.819");
Runtime error: UNIQUE constraint failed: sessions.app_name, sessions.user_id, sessions.id (19)
This needs to be an UPDATE query
Making the following change resolves the issue, not sure if it's really the desired behavior, but using Save instead of Create matches the two database calls above it (for app_state and user_state)
https://github.com/google/adk-go/blob/main/session/database/service.go#L124
diff --git a/session/database/service.go b/session/database/service.go
index 56e808a..0c2f6c7 100644
--- a/session/database/service.go
+++ b/session/database/service.go
@@ -121,7 +121,7 @@ func (s *databaseService) Create(ctx context.Context, req *session.CreateRequest
}
createdSession.State = sessionState
- if err := tx.Create(createdSession).Error; err != nil {
+ if err := tx.Save(createdSession).Error; err != nil {
return fmt.Errorf("error creating session on database: %w", err)
}
From my personal perspective, it would be nice to have the Update API to update the session. But not sure if the API needs to align with adk-python. It would be great if maintainers could suggest on this. @dpasiukevich