siyuan-note/siyuan · error
unsupported template database mode [%s]
Error message
unsupported template database mode [%s]
What it means
DocSaveAsTemplateInDirectory saves the current document as a template and decides how embedded attribute views (databases) are handled. databaseMode must be exactly TemplateDatabaseModeCopy (copy) or TemplateDatabaseModeReference (reference); empty defaults to copy. Any other string aborts with this error before any file is written.
Source
Thrown at kernel/model/template.go:271
}
func DocSaveAsTemplate(id, name string, overwrite bool) (code int, err error) {
return DocSaveAsTemplateWithDatabaseMode(id, name, overwrite, TemplateDatabaseModeCopy)
}
func DocSaveAsTemplateWithDatabaseMode(id, name string, overwrite bool, databaseMode TemplateDatabaseMode) (code int, err error) {
return DocSaveAsTemplateInDirectory(id, name, "", overwrite, databaseMode)
}
func DocSaveAsTemplateInDirectory(id, name, directory string, overwrite bool, databaseMode TemplateDatabaseMode) (code int, err error) {
if err = validateTemplateRelativePath(directory, true); err != nil {
return
}
if databaseMode == "" {
databaseMode = TemplateDatabaseModeCopy
}
if TemplateDatabaseModeCopy != databaseMode && TemplateDatabaseModeReference != databaseMode {
return 0, fmt.Errorf("unsupported template database mode [%s]", databaseMode)
}
bt := treenode.GetBlockTree(id)
if nil == bt {
return
}
tree := prepareExportTree(bt)
markTemplateAttributeViewModes(tree.Root, databaseMode)
addBlockIALNodes(tree, true)
ast.Walk(tree.Root, func(n *ast.Node, entering bool) ast.WalkStatus {
if !entering {
return ast.WalkContinue
}
// Content in templates is not properly escaped
// https://github.com/siyuan-note/siyuan/issues/9649View on GitHub (pinned to 8641553a1f)
Solutions
- Use the constants: model.TemplateDatabaseModeCopy or model.TemplateDatabaseModeReference
- Pass the exact lowercase strings copy or reference when calling over the HTTP API
- Pass an empty string to get the default (copy) behavior instead of inventing a value
Example fix
// before model.DocSaveAsTemplateWithDatabaseMode(id, dir, 'ref') // after model.DocSaveAsTemplateWithDatabaseMode(id, dir, model.TemplateDatabaseModeReference)
Defensive patterns
Strategy: validation
Validate before calling
mode := strings.TrimSpace(databaseMode)
if mode != '' && mode != 'copy' && mode != 'reference' {
return fmt.Errorf('unsupported template database mode %q', mode)
} Type guard
func validDBMode(m model.TemplateDatabaseMode) bool {
return m == model.TemplateDatabaseModeCopy || m == model.TemplateDatabaseModeReference || m == ''
} Try / catch
id, err := model.DocSaveAsTemplateWithDatabaseMode(id, dir, mode)
if err != nil {
if strings.Contains(err.Error(), 'unsupported template database mode') {
return fmt.Errorf('mode must be copy or reference, got %q', mode)
}
return err
} Prevention
- Only use exported TemplateDatabaseMode* constants in Go callers
- In JS clients, hard-code the exact lowercase literals copy/reference
- Treat empty string as valid (defaults to copy) rather than substituting your own default word
When it happens
Trigger: Calling DocSaveAsTemplateInDirectory / DocSaveAsTemplateWithDatabaseMode / the docSaveAsTemplate API with databaseMode set to values like Copy, ref, link, duplicate, or a misspelled variant.
Common situations: API clients guessing mode strings, UI plugins passing translated labels instead of the enum value, or stale code written against an older parameter set.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/bdec121b0065e13e.
Report an issue: GitHub.