siyuan-note/siyuan · error
template requires a template field; use renderTemplate for…
Error message
template requires a template field; use renderTemplate for other fields
What it means
The "template" setting is only valid for fields of type KeyTypeTemplate; other field types must use "renderTemplate" to set their rendered template. Passing "template" for a non-template field is rejected to keep template-type configuration separate from display-render templates.
Solutions
- Use {"renderTemplate": "..."} for non-template fields
- Create the field as a template type first if a computed formula column is wanted
- Branch on key.Type in client code: template -> "template", anything else -> "renderTemplate"
Example fix
// before
updateKeyConfig(avID, textKeyID, {"template": "{name}"})
// after
updateKeyConfig(avID, textKeyID, {"renderTemplate": "{name}"}) Defensive patterns
Strategy: validation
Validate before calling
function assertTemplateSetting(key, setting) { if (setting === 'template' && key.type !== 'template') throw new Error('use renderTemplate for non-template fields'); if (setting === 'renderTemplate' && key.type === 'template') throw new Error('use template for a template field'); } Type guard
const isTemplateField = (key) => key?.type === 'template';
Try / catch
try { await updateKeyConfig(avID, keyID, { template: value }); } catch (e) { if (/template requires a template field/.test(e.message)) { return updateKeyConfig(avID, keyID, { renderTemplate: value }); } throw e; } Prevention
- Branch on field type: template fields use "template", all others use "renderTemplate"
- Copy API examples from matching field types only
- Wrap config updates in a helper that maps setting name to field type
When it happens
Trigger: Calling UpdateAttributeViewKeyConfig with {"template": ".foo"} on a text, number, or date field instead of {"renderTemplate": ...}.
Common situations: Plugin authors confusing the template field formula with the render template of regular columns; API payloads copied from template-field examples and reused for other column types.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- numberFormat requires a number field and a supported format
- config must contain exactly one setting; use separate calls…
- Field [keyIDs] is required
- field name must not be empty
- Field [ ] is required
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/dd5f0850928c0d7a.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/attribute_view_key_config.go:75
if _, err = newAttributeViewKey(keyID, key.Name, text, key.Icon, key.DateFormat); nil != err {
return err
}
op.Typ = text
return updateAttributeViewColumn(op)
case "icon":
return setAttributeViewColIcon(op)
case "desc":
return setAttributeViewColDesc(op)
case "numberFormat":
if av.KeyTypeNumber != key.Type || !slices.Contains(AttributeViewKeyNumberFormats, text) {
return errors.New("numberFormat requires a number field and a supported format")
}
return updateAttributeViewColNumberFormat(op)
case "dateFormat":
return setAttributeViewColDateFormat(op)
case "template":
if av.KeyTypeTemplate != key.Type {
return errors.New("template requires a template field; use renderTemplate for other fields")
}
return updateAttributeViewColTemplate(op)
case "renderTemplate":
if av.KeyTypeTemplate == key.Type {
return errors.New("use template for a template field")
}
return updateAttributeViewColTemplate(op)
}
case "autoFillNow", "fillSpecificTime", "includeTime":
flag, ok := value.(bool)
if !ok {
return fmt.Errorf("%s must be a boolean", setting)
}
op.Data = flag
if "includeTime" == setting {
switch key.Type {
case av.KeyTypeCreated:
return setAttrViewCreatedIncludeTime(op)View on GitHub (pinned to 9f775e8a12)