siyuan-note/siyuan · error
email value is missing
Error message
email value is missing
What it means
When the key type is KeyTypeEmail, the value must carry a non-nil Value.Email object; otherwise normalization fails with 'email value is missing'. The function rejects the value so invalid template data never reaches the attribute view.
Solutions
- Add the email object: {"email":{"content":"user@example.com"}}
- Use the text type if the content is not a real email field
- Drop the value so pruning silently removes it
- Validate Value.Email != nil for every email-typed value before calling
Example fix
// before
{"type":"email"}
// after
{"type":"email","email":{"content":"user@example.com"}} Defensive patterns
Strategy: validation
Validate before calling
if v.Type == av.KeyTypeEmail && v.Email == nil {
return fmt.Errorf("email value requires an email object")
} Type guard
func hasEmail(v *av.Value) bool { return v != nil && v.Type == av.KeyTypeEmail && v.Email != nil } Prevention
- Put the address in Value.Email.Content, never Value.Text
- Validate each typed field's payload before normalization
- Test templates end-to-end through PruneInvalidNewItemTemplateFieldValues
When it happens
Trigger: A value passed through PruneInvalidNewItemTemplateFieldValues or normalizeNewItemTemplateFieldValues with KeyTypeEmail and Value.Email == nil (email sub-object omitted from the JSON).
Common situations: Copy-pasting a URL/text template value and switching the type to email without adding the email object; API consumers assuming the email content lives in Value.Text.
Related errors
- checkbox value is missing
- date value is missing
- phone value is missing
- URL value is missing
- at least one visible view is required
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/3869d38821e82c0e.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/av/new_item_template.go:393
var selections []*ValueSelect
for _, selection := range value.MSelect {
if nil != selection && "" != strings.TrimSpace(selection.Content) {
selections = append(selections, selection)
}
}
if KeyTypeSelect == key.Type && 1 < len(selections) {
selections = selections[:1]
}
value.MSelect = selections
value.Text, value.Number, value.Date, value.URL, value.Email, value.Phone, value.MAsset, value.Checkbox, value.Relation = nil, nil, nil, nil, nil, nil, nil, nil, nil
case KeyTypeURL:
if nil == value.URL {
return nil, errors.New("URL value is missing")
}
value.Text, value.Number, value.Date, value.MSelect, value.Email, value.Phone, value.MAsset, value.Checkbox, value.Relation = nil, nil, nil, nil, nil, nil, nil, nil, nil
case KeyTypeEmail:
if nil == value.Email {
return nil, errors.New("email value is missing")
}
value.Text, value.Number, value.Date, value.MSelect, value.URL, value.Phone, value.MAsset, value.Checkbox, value.Relation = nil, nil, nil, nil, nil, nil, nil, nil, nil
case KeyTypePhone:
if nil == value.Phone {
return nil, errors.New("phone value is missing")
}
value.Text, value.Number, value.Date, value.MSelect, value.URL, value.Email, value.MAsset, value.Checkbox, value.Relation = nil, nil, nil, nil, nil, nil, nil, nil, nil
case KeyTypeMAsset:
var assets []*ValueAsset
for _, asset := range value.MAsset {
if nil != asset && "" != strings.TrimSpace(asset.Content) {
if AssetTypeFile != asset.Type && AssetTypeImage != asset.Type {
return nil, fmt.Errorf("invalid asset type [%s]", asset.Type)
}
assets = append(assets, asset)
}
}
value.MAsset = assetsView on GitHub (pinned to 9f775e8a12)