siyuan-note/siyuan · error
invalid attribute view field template
Error message
invalid attribute view field template
What it means
setAttributeViewFieldTemplate updates a template-type column's template. The kernel asserts operation.Data is the raw template string; if the assertion fails (Data is not a Go string), it returns this error and the template is not applied. This rejects malformed payloads before the template is compiled or stored.
Source
Thrown at kernel/model/attribute_view.go:7494
}
func (tx *Transaction) doUpdateAttrViewColTemplate(operation *Operation) (ret *TxErr) {
err := updateAttributeViewColTemplate(operation)
if err != nil {
return &TxErr{code: TxErrHandleAttributeView, id: operation.AvID, msg: err.Error()}
}
return
}
func updateAttributeViewColTemplate(operation *Operation) (err error) {
attrView, err := av.ParseAttributeView(operation.AvID)
if err != nil {
return
}
templateContent, ok := operation.Data.(string)
if !ok {
return errors.New("invalid attribute view field template")
}
colType := av.KeyType(operation.Typ)
for _, keyValues := range attrView.KeyValues {
if keyValues.Key.ID != operation.ID || keyValues.Key.Type != colType {
continue
}
if av.KeyTypeTemplate == colType {
keyValues.Key.Template = templateContent
} else {
keyValues.Key.RenderTemplate = templateContent
}
break
}
regenAttrViewGroups(attrView)
err = av.SaveAttributeView(attrView)
return
}View on GitHub (pinned to 8641553a1f)
Solutions
- Send the template as a plain string in operation.Data, e.g. "=join(now(), " - ")" — not an object or JSON-encoded wrapper.
- Check that the client builds the operation with Data: templateText directly.
- Validate the template is a non-empty string before queuing the transaction.
Example fix
// before
Operation{Action: "setAttrViewFieldTemplate", ID: keyID, Data: map[string]any{"template": tpl}}
// after
Operation{Action: "setAttrViewFieldTemplate", ID: keyID, Data: tpl} Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof templateText !== "string" || templateText.length === 0) throw new Error("template must be a non-empty string"); Type guard
const isTemplateString = (v) => typeof v === "string";
Try / catch
try { await setAttrViewFieldTemplate(op); } catch (e) { if (String(e).includes("invalid attribute view field template")) { console.error("Data must be the raw template string, not an object", e); } else { throw e; } } Prevention
- Assign the template text directly to operation.Data — no wrapper object, no JSON.stringify
- Check for undefined template UI state before building the operation
- Test the exact operation payload your plugin sends via the transactions API
When it happens
Trigger: setAttrViewFieldTemplate operation whose Data is nil, a map, a number, or another non-string value instead of the template text (e.g. sending a serialized JSON wrapper or a parsed object).
Common situations: Plugin wrapping the template in an object like {"template": "..."} instead of sending the plain string; scripts passing a JSON-encoded string of an object; UI state not yet initialized (undefined) when building the operation.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- database [%s] template field [%s] rendering failed: %s
- parse template [%s] failed: %s
- execute template [%s] failed: %s
- relation value is missing
- unsupported value type [%s]
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/908396abe905e6c0.
Report an issue: GitHub.