siyuan-note/siyuan · error
invalid session id
Error message
invalid session id
What it means
GetSessionState (kernel/agent/session.go:285) validates the requested session id against SiYuan's block-ID pattern (ast.IsNodeIDPattern — exactly 20 chars of [0-9a-z]) before touching disk. An empty string or anything that is not a canonical 20-char id yields 'invalid session id'. Sessions are created by the agent itself, so ids always come from lsSessions/getSession responses, never from user input.
Source
Thrown at kernel/agent/session.go:286
}
}
end := min(start+pageSize, total)
return &SessionListResult{
Sessions: items[start:end],
Total: total,
Page: page,
PageSize: pageSize,
}
}
func GetSession(id string) (map[string]any, error) {
return GetSessionState(id, true)
}
func GetSessionState(id string, includeRuntime bool) (map[string]any, error) {
if id == "" || !isValidSessionID(id) {
return nil, fmt.Errorf("invalid session id")
}
lock := sessionLock(id)
lock.Lock()
defer lock.Unlock()
sessionPath := filepath.Join(sessionsDir(), id, "session.json")
data, err := os.ReadFile(sessionPath)
if err != nil {
return nil, err
}
var session map[string]any
if err := gulu.JSON.UnmarshalJSON(data, &session); err != nil {
return nil, err
}
if includeRuntime {
if err := mergeRuntimeIntoSessionLocked(id, session); err != nil {
return nil, err
}View on GitHub (pinned to afa823b6b4)
Solutions
- Always take the id from the lsSessions response's sessions[].id field
- If generating a test session, use a real 20-char [0-9a-z] id and create the session via saveSession first
- Trim whitespace and lowercase the value before sending
- Return a 400-style message to the UI instead of retrying — this error is not transient
Example fix
// before
fetchPost('/api/ai/agent/getSession', {id: sessionTitle});
// after
const list = await fetchPost('/api/ai/agent/lsSessions', {page: 1, pageSize: 30});
const item = list.data.sessions.find(s => s.title === sessionTitle);
if (item) fetchPost('/api/ai/agent/getSession', {id: item.id}); Defensive patterns
Strategy: validation
Validate before calling
const SESSION_ID_RE = /^[0-9a-z]{20}$/;
const ok = typeof id === 'string' && SESSION_ID_RE.test(id);
if (!ok) throw new Error('invalid session id'); Type guard
const isValidSessionID = (id: unknown): id is string =>
typeof id === 'string' && /^[0-9a-z]{20}$/.test(id); Try / catch
null
Prevention
- Source ids only from lsSessions/getSession responses
- Never accept free-text ids from the UI for session operations
- Assert the 20-char [0-9a-z] pattern at the boundary where ids enter your code
When it happens
Trigger: POST /api/ai/agent/getSession with {"id": ""}, a truncated id, an id containing uppercase/whitespace/hyphens, or a value that is actually the session title or index position. Also triggered by internal callers passing an unvalidated external string to agent.GetSession/GetSessionState.
Common situations: Frontend typos or hand-constructed test ids; passing an object {id: {…}} so JSON binding yields ""; ids mangled by URL encoding or copy-paste; using a database row id from another system.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- invalid session data
- agent session revision conflict
- decode session data failed: %w
- decode existing session data failed: %w
- read session file failed: %w
AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18).
Data as JSON: /api/errors/33fdc86eb94e6ed2.
Report an issue: GitHub.