siyuan-note/siyuan · error

invalid agent permission mode

Error message

invalid agent permission mode

What it means

resolveSessionPermissionModeLoaded reads the persisted agent runtime (runtime.json) and, when it contains a permissionMode, validates it against the allowed modes "confirm" and "allowSession". This error means runtime.json holds a permissionMode string outside that set, so the kernel cannot decide how to gate the session's tool calls. It is a data-integrity guard against a corrupted or hand-edited runtime file.

Source

Thrown at kernel/agent/runtime.go:67

type sessionPermissionController struct {
	allowSession atomic.Bool
}

var sessionPermissionControllers sync.Map

func validAgentPermissionMode(mode string) bool {
	return mode == AgentPermissionConfirm || mode == AgentPermissionAllowSession
}

func resolveSessionPermissionModeLocked(sessionID string, session map[string]any) (string, error) {
	runtime, err := loadRuntimeLocked(sessionID)
	if err != nil {
		return "", err
	}
	if runtime.PermissionMode != "" {
		if !validAgentPermissionMode(runtime.PermissionMode) {
			return "", fmt.Errorf("invalid agent permission mode")
		}
		return runtime.PermissionMode, nil
	}
	if runtime.AlwaysAllow {
		return AgentPermissionAllowSession, nil
	}
	if session == nil {
		data, readErr := os.ReadFile(filepath.Join(sessionsDir(), sessionID, "session.json"))
		if readErr != nil {
			return "", readErr
		}
		session = map[string]any{}
		if unmarshalErr := gulu.JSON.UnmarshalJSON(data, &session); unmarshalErr != nil {
			return "", unmarshalErr
		}
	}
	if permissionMode, _ := session["permissionMode"].(string); permissionMode != "" {
		if !validAgentPermissionMode(permissionMode) {

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Open data/storage/ai/agent/sessions/<sessionID>/runtime.json and change permissionMode to "confirm" or "allowSession"
  2. Or remove the permissionMode field entirely so the resolver falls back to legacy alwaysAllow/session.json defaults
  3. If the file is corrupt, delete runtime.json for that session; it will be recreated with the default "confirm" mode
  4. Verify the kernel version is not a downgrade that lacks the mode value stored in the file

Example fix

// before (runtime.json)
"permissionMode": "allow"
// after
"permissionMode": "confirm"
Defensive patterns

Strategy: validation

Validate before calling

func validAgentPermissionMode(mode string) bool { return mode == "confirm" || mode == "allowSession" }
// before resolving: if mode := runtime.PermissionMode; mode != "" && !validAgentPermissionMode(mode) { return fmt.Errorf("...") }

Type guard

func isAgentPermissionMode(v any) bool { s, ok := v.(string); return ok && (s == "confirm" || s == "allowSession") }

Try / catch

mode, err := resolveSessionPermissionMode(sessionID)
if err != nil {
    log.Warnf("falling back to default permission mode: %v", err)
    mode = "confirm"
}

Prevention

When it happens

Trigger: Calling GetSessionState or registering a session permission controller (e.g. when opening/running an agent session) where the session's runtime.json has permissionMode set to a string other than "confirm" or "allowSession".

Common situations: Hand-editing or script-modifying data/storage/ai/agent/sessions/<id>/runtime.json with an unsupported mode like "allow", "always", or "auto"; a downgrade from a newer version that had extra modes; truncated/corrupted JSON producing a stale field value.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/7b41f279d89b5642. Report an issue: GitHub.