siyuan-note/siyuan · error

invalid date display format

Error message

invalid date display format

What it means

Thrown by AddAttributeViewKey when adding a date, created, or updated key whose dateFormat does not pass av.DateDisplayFormat.IsValid(). The format must be one of the recognized date-display-format enum values; any other string is rejected before the key is created.

Source

Thrown at kernel/model/attribute_view.go:6968

	}

	currentView, err := getAttrViewViewByBlockID(attrView, blockID)
	if nil != err {
		return
	}

	keyTyp := av.KeyType(keyType)
	switch keyTyp {
	case av.KeyTypeBlock:
		return errors.New("cannot add an attribute view block key")
	case av.KeyTypeText, av.KeyTypeNumber, av.KeyTypeDate, av.KeyTypeSelect, av.KeyTypeMSelect, av.KeyTypeURL, av.KeyTypeEmail,
		av.KeyTypePhone, av.KeyTypeMAsset, av.KeyTypeTemplate, av.KeyTypeCreated, av.KeyTypeUpdated, av.KeyTypeCheckbox,
		av.KeyTypeRelation, av.KeyTypeRollup, av.KeyTypeLineNumber:

		key := av.NewKey(keyID, keyName, filterAttrViewIconValue(keyIcon), keyTyp)
		if av.KeyTypeDate == keyTyp || av.KeyTypeCreated == keyTyp || av.KeyTypeUpdated == keyTyp {
			if !dateFormat.IsValid() {
				return errors.New("invalid date display format")
			}
			key.DateFormat = dateFormat
		}
		if av.KeyTypeRollup == keyTyp {
			key.Rollup = &av.Rollup{Calc: &av.RollupCalc{Operator: av.CalcOperatorNone}}
		}

		attrView.KeyValues = append(attrView.KeyValues, &av.KeyValues{Key: key})

		for _, view := range attrView.Views {
			newField := &av.BaseField{ID: key.ID}
			if nil != view.Table {
				newField.Wrap = view.Table.WrapField

				if "" == previousKeyID {
					if av.LayoutTypeGallery == currentView.LayoutType || av.LayoutTypeKanban == currentView.LayoutType {
						// 如果当前视图是卡片或看板视图则添加到最后
						view.Table.Columns = append(view.Table.Columns, &av.ViewTableColumn{BaseField: newField})

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Use only date-format values returned by the kernel's format enumeration when constructing add-column operations for date/created/updated keys.
  2. Default to a known-good format (e.g. the kernel's default) when the user does not pick one, instead of sending an empty string.
  3. Align frontend and kernel versions so the format enum sets match.

Example fix

// before
AddAttributeViewKey(avID, blockID, keyID, name, 'date', icon, prevID, '')
// after
AddAttributeViewKey(avID, blockID, keyID, name, 'date', icon, prevID, av.DateDisplayFormatYYYYMMDD) // a valid enum member
Defensive patterns

Strategy: validation

Validate before calling

const VALID_DATE_FORMATS = await fetchValidDateFormats() // from kernel enum
if (['date','created','updated'].includes(op.type) && !VALID_DATE_FORMATS.includes(op.format)) {
  op.format = VALID_DATE_FORMATS[0] // default to a known-good value
}

Prevention

When it happens

Trigger: Sending operation.Format with an empty string, a custom format, or a value from an older/newer kernel version whose enum set differs. Reached when a caller omits Format for a date-type key or passes a raw moment/dayjs format string instead of the kernel enum.

Common situations: Frontend version skew (new format value not yet known to the running kernel); a plugin hard-coding a format string; manual API call that leaves Format blank.

Related errors


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