siyuan-note/siyuan · error
relation value is missing
Error message
relation value is missing
What it means
For KeyTypeRelation values, normalizeNewItemTemplateValue requires a non-nil Value.Relation object; otherwise it fails with 'relation value is missing'. Relation template values must identify the related blocks via Relation.BlockIDs, which the nil object cannot.
Solutions
- Populate the Relation object with the related block IDs
- Use an empty Relation {"relation":{"blockIDs":[]}} if no blocks are related yet
- Change the value type if no relation semantics are needed
- Remove the invalid value prior to pruning
Example fix
// before
{"type":"relation"}
// after
{"type":"relation","relation":{"blockIDs":["20240101120000-abcdef"]}} Defensive patterns
Strategy: validation
Validate before calling
if v.Type == av.KeyTypeRelation && v.Relation == nil {
return fmt.Errorf("relation value requires a relation object")
} Type guard
func hasRelation(v *av.Value) bool { return v != nil && v.Type == av.KeyTypeRelation && v.Relation != nil } Prevention
- Initialize Relation (even with empty BlockIDs) for relation-typed values
- Resolve relations via the API so BlockIDs are populated correctly
- Validate templates after every schema change
When it happens
Trigger: A value passed through PruneInvalidNewItemTemplateFieldValues or normalizeNewItemTemplateFieldValues with KeyTypeRelation and Value.Relation == nil (relation object missing from the template value).
Common situations: Templates created before a relation was linked (no BlockIDs yet); plugins generating relation rows without populating the Relation struct.
Related errors
- at least one visible view is required
- attribute view custom color index
- attribute view custom color must not be null
- attribute view custom colors count exceeds the
- attribute view custom colors must not be empty
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/d78d368ea57f35bd.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/av/new_item_template.go:420
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 = assets
value.Text, value.Number, value.Date, value.MSelect, value.URL, value.Email, value.Phone, value.Checkbox, value.Relation = nil, nil, nil, nil, nil, nil, nil, nil, nil
case KeyTypeCheckbox:
if nil == value.Checkbox {
return nil, errors.New("checkbox value is missing")
}
value.Text, value.Number, value.Date, value.MSelect, value.URL, value.Email, value.Phone, value.MAsset, value.Relation = nil, nil, nil, nil, nil, nil, nil, nil, nil
case KeyTypeRelation:
if nil == value.Relation {
return nil, errors.New("relation value is missing")
}
for _, blockID := range value.Relation.BlockIDs {
if !ast.IsNodeIDPattern(blockID) {
return nil, fmt.Errorf("invalid relation block ID [%s]", blockID)
}
}
value.Text, value.Number, value.Date, value.MSelect, value.URL, value.Email, value.Phone, value.MAsset, value.Checkbox = nil, nil, nil, nil, nil, nil, nil, nil, nil
default:
return nil, fmt.Errorf("unsupported value type [%s]", key.Type)
}
value.Block, value.Template, value.Created, value.Updated, value.Rollup = nil, nil, nil, nil, nil
value.ID = ""
value.KeyID = ""
value.BlockID = ""
value.Type = key.Type
value.IsDetached = false
value.CreatedAt = 0
value.UpdatedAt = 0View on GitHub (pinned to 9f775e8a12)