{"record":{"id":"908396abe905e6c0","repo":"siyuan-note/siyuan","slug":"invalid-attribute-view-field-template","errorCode":null,"errorMessage":"invalid attribute view field template","messagePattern":"invalid attribute view field template","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/attribute_view.go","lineNumber":7494,"sourceCode":"}\n\nfunc (tx *Transaction) doUpdateAttrViewColTemplate(operation *Operation) (ret *TxErr) {\n\terr := updateAttributeViewColTemplate(operation)\n\tif err != nil {\n\t\treturn &TxErr{code: TxErrHandleAttributeView, id: operation.AvID, msg: err.Error()}\n\t}\n\treturn\n}\n\nfunc updateAttributeViewColTemplate(operation *Operation) (err error) {\n\tattrView, err := av.ParseAttributeView(operation.AvID)\n\tif err != nil {\n\t\treturn\n\t}\n\n\ttemplateContent, ok := operation.Data.(string)\n\tif !ok {\n\t\treturn errors.New(\"invalid attribute view field template\")\n\t}\n\tcolType := av.KeyType(operation.Typ)\n\tfor _, keyValues := range attrView.KeyValues {\n\t\tif keyValues.Key.ID != operation.ID || keyValues.Key.Type != colType {\n\t\t\tcontinue\n\t\t}\n\t\tif av.KeyTypeTemplate == colType {\n\t\t\tkeyValues.Key.Template = templateContent\n\t\t} else {\n\t\t\tkeyValues.Key.RenderTemplate = templateContent\n\t\t}\n\t\tbreak\n\t}\n\n\tregenAttrViewGroups(attrView)\n\terr = av.SaveAttributeView(attrView)\n\treturn\n}","sourceCodeStart":7476,"sourceCodeEnd":7512,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/attribute_view.go#L7476-L7512","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nOperation{Action: \"setAttrViewFieldTemplate\", ID: keyID, Data: map[string]any{\"template\": tpl}}\n// after\nOperation{Action: \"setAttrViewFieldTemplate\", ID: keyID, Data: tpl}","handlingStrategy":"type-guard","validationCode":"if (typeof templateText !== \"string\" || templateText.length === 0) throw new Error(\"template must be a non-empty string\");","typeGuard":"const isTemplateString = (v) => typeof v === \"string\";","tryCatchPattern":"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; } }","preventionTips":["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"],"tags":["attribute-view","template","type-assertion"],"backgroundTag":"type-mismatch","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}