siyuan-note/siyuan · error
invalid AI editor action data
Error message
invalid AI editor action data
What it means
After parsing, loadAIEditorActions (kernel/model/ai_editor.go:175) sanity-checks every entry: it must be non-nil, its ID must match the node-ID pattern, and it must have a name or an action prompt. Any violation returns this generic data error — the file parses as JSON and has the right version, but its contents were not produced by the kernel.
Source
Thrown at kernel/model/ai_editor.go:175
data, err := filelock.ReadFile(dataPath)
if err != nil {
return nil, fmt.Errorf("read AI editor actions failed: %w", err)
}
if err = gulu.JSON.UnmarshalJSON(data, ret); err != nil {
return nil, fmt.Errorf("unmarshal AI editor actions failed: %w", err)
}
if ret.Version != aiEditorActionsVersion {
return nil, fmt.Errorf("unsupported AI editor actions version [%d]", ret.Version)
}
if ret.Actions == nil {
ret.Actions = []*AIEditorAction{}
}
ids := make(map[string]struct{}, len(ret.Actions))
for _, action := range ret.Actions {
if action == nil || !ast.IsNodeIDPattern(action.ID) || (action.Name == "" && action.Action == "") {
return nil, errors.New("invalid AI editor action data")
}
if _, ok := ids[action.ID]; ok {
return nil, fmt.Errorf("duplicate AI editor action ID [%s]", action.ID)
}
ids[action.ID] = struct{}{}
}
return ret, nil
}
func saveAIEditorActions(data *aiEditorActionsData) (err error) {
data.Version = aiEditorActionsVersion
if data.Actions == nil {
data.Actions = []*AIEditorAction{}
}
dirPath := filepath.Dir(aiEditorActionsPath())
if err = os.MkdirAll(dirPath, 0755); err != nil {
return fmt.Errorf("create AI editor actions directory failed: %w", err)View on GitHub (pinned to afa823b6b4)
Solutions
- Open actions.json and fix each entry to the kernel shape: {"id":"<14-digit-time>-<7-char-suffix>","name":"...","action":"..."} with at least one of name/action non-empty
- Give hand-added entries a correctly shaped unique ID, e.g. timestamp-based 20240101120000-a1b2c3d that no other entry uses
- Or delete/rename the file — defaults are regenerated and legacy actions re-imported from localStorage
Example fix
// before: {"version":1,"actions":[{"name":"Translate"}]}
// after: {"version":1,"actions":[{"id":"20240101120000-a1b2c3d","name":"Translate","action":"Translate to English:\n{content}"}]} Defensive patterns
Strategy: try-catch
Validate before calling
var nodeIDPattern = regexp.MustCompile(`^[0-9]{14}-[a-z0-9]{7}$`)
func validEntries(actions []*AIEditorAction) bool {
for _, a := range actions {
if a == nil || !nodeIDPattern.MatchString(a.ID) || (a.Name == "" && a.Action == "") {
return false
}
}
return true
} Type guard
function isWellFormedAction(a: any): boolean {
return (
!!a &&
typeof a.id === "string" && /^[0-9]{14}-[a-z0-9]{7}$/.test(a.id) &&
(typeof a.name === "string" || typeof a.action === "string") &&
((a.name ?? "") !== "" || (a.action ?? "") !== "")
);
} Try / catch
if err != nil && err.Error() == "invalid AI editor action data" {
// inspect actions.json entries one by one; fix shape or reset the file
backupAndResetActionsFile()
return
} Prevention
- Only let the kernel write actions.json; script edits must mimic the exact shape including valid IDs
- Validate imported action lists entry-by-entry before writing them
- Prefer delete-and-recreate over surgical file edits when repairing
When it happens
Trigger: actions.json entries like null in the actions array, {"name":"x"} with no id, an id like "foo", or an entry with both name and action empty. Typically follows a hand edit or a bad merge from a sync tool rather than kernel writes, which always assign valid IDs.
Common situations: Hand-crafted action files missing the id field (the server always writes one); a JSON merge that dropped fields; copy-pasting an action between files without the id; nulls introduced by script-generated files.
Related errors
- unmarshal AI editor actions failed: %w
- duplicate AI editor action ID [%s]
- provider base URL is required
- parse [h] failed: %s
- invalid JSON: %s
AI-assisted analysis of siyuan-note/siyuan@afa823b6b4 (2026-08-18).
Data as JSON: /api/errors/28fcf38c71f5ba77.
Report an issue: GitHub.