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

  1. Always take the id from the lsSessions response's sessions[].id field
  2. If generating a test session, use a real 20-char [0-9a-z] id and create the session via saveSession first
  3. Trim whitespace and lowercase the value before sending
  4. 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

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


AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18). Data as JSON: /api/errors/33fdc86eb94e6ed2. Report an issue: GitHub.