siyuan-note/siyuan · error

agent runtime user entry not found

Error message

agent runtime user entry not found

What it means

Rejected by siyuan.storage.watcher.add(path) when no argument is supplied or the first argument is not a string (kernel/plugin/api_storage.go:59). The watcher API needs a concrete path (or relative key) inside the plugin storage to subscribe to; missing, undefined, null, or non-string values are rejected before path resolution runs, so unlike get/put it cannot even attempt an empty path.

Source

Thrown at kernel/agent/runtime.go:456

		if entry["type"] != "user" {
			continue
		}
		id, _ := entry["id"].(string)
		if userEntryID == "" || id == userEntryID {
			return i
		}
	}
	return -1
}

func applyRuntimeTurnToSessionLocked(session map[string]any, turn *agentRuntimeTurn) error {
	if turn == nil {
		return nil
	}
	entries, _ := session["entries"].([]any)
	anchor := findRuntimeUserAnchor(session, turn.UserEntryID)
	if anchor < 0 {
		return fmt.Errorf("agent runtime user entry not found")
	}
	if turn.Mode == "regenerate" && turn.UserContent != "" {
		entry, _ := entries[anchor].(map[string]any)
		entry["content"] = turn.UserContent
		if turn.UserBlockHTML != nil {
			if *turn.UserBlockHTML != "" {
				entry["blockHTML"] = *turn.UserBlockHTML
			} else {
				delete(entry, "blockHTML")
			}
		}
		if turn.UserReferences != nil {
			if len(*turn.UserReferences) > 0 {
				entry["references"] = *turn.UserReferences
			} else {
				delete(entry, "references")
			}
		}

View on GitHub (pinned to afa823b6b4)

Solutions

  1. Pass a string path: await siyuan.storage.watcher.add('notes')
  2. Skip the call when the configured path is missing rather than calling with undefined
  3. Validate the config at plugin load and fall back to a default watch path

Example fix

// before
await siyuan.storage.watcher.add(cfg.watchPath); // undefined when unset

// after
if (typeof cfg.watchPath === 'string' && cfg.watchPath) {
  await siyuan.storage.watcher.add(cfg.watchPath);
}
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof cfg.watchPath === 'string' && cfg.watchPath.length > 0) {
  await siyuan.storage.watcher.add(cfg.watchPath);
}

Type guard

const isNonEmptyString = (v) => typeof v === 'string' && v.length > 0;

Try / catch

try { await siyuan.storage.watcher.add(path); } catch (e) { if (/path required/.test(e.message)) console.error('watch path missing from settings'); else throw e; }

Prevention

When it happens

Trigger: watcher.add() with no argument; watcher.add(undefined) from an unset config key; watcher.add(5) or watcher.add({path: 'x'}) passing the wrong type.

Common situations: Optional watch-path settings that default to undefined; refactors extracting the path into a variable that is only conditionally assigned; passing the whole settings object instead of the field.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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