siyuan-note/siyuan · error

invalid asset type [%s]

Error message

invalid asset type [%s]

What it means

Thrown inside normalizeNewItemTemplateValue (kernel/av/new_item_template.go:405-406) during the KeyTypeMAsset branch. After filtering out nil/empty assets, each remaining asset's Type field is checked against exactly two constants: AssetTypeFile ("file") and AssetTypeImage ("image"). Any other type string triggers this formatted error. This is the only content-validating check in the MAsset branch; nil MAsset slices are tolerated (they just produce an empty assets slice).

Source

Thrown at kernel/av/new_item_template.go:406

			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 = 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)

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Set every asset.Type to exactly "file" or "image" (lowercase ASCII)
  2. Remove assets with unrecognized types from the MAsset slice before submitting
  3. Check kernel/av/value.go:821-822 for the canonical constants AssetTypeFile and AssetTypeImage

Example fix

// before
value.MAsset = []*av.ValueAsset{{Type: "link", Content: "https://example.com"}}
// after
value.MAsset = []*av.ValueAsset{{Type: av.AssetTypeFile, Content: "https://example.com"}}
Defensive patterns

Strategy: validation

Validate before calling

func validateMAssetTypes(value *av.Value) error {
    for _, asset := range value.MAsset {
        if asset == nil || strings.TrimSpace(asset.Content) == "" {
            continue
        }
        if asset.Type != av.AssetTypeFile && asset.Type != av.AssetTypeImage {
            return fmt.Errorf("asset type must be %q or %q, got %q", av.AssetTypeFile, av.AssetTypeImage, asset.Type)
        }
    }
    return nil
}

Type guard

func isValidAssetType(t string) bool {
    return t == av.AssetTypeFile || t == av.AssetTypeImage
}

Prevention

When it happens

Trigger: An mAsset-type template field value contains a ValueAsset whose Type is neither "file" nor "image" — for example "link", "video", "audio", or a typo like "File".

Common situations: Third-party tooling that generates AV values with non-standard asset types; manual JSON editing that guesses the type enum incorrectly; copy-pasting asset values from a different data model.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/4e78abba0d837ec6. Report an issue: GitHub.