siyuan-note/siyuan · error

date display format is only available for date fields

Error message

date display format is only available for date fields

What it means

Thrown by setAttributeViewColDateFormat when operation.Typ is not one of KeyTypeDate, KeyTypeCreated, or KeyTypeUpdated. Date display format is only meaningful for those three column types; applying it to text, number, select, etc. is rejected because it would have no effect and would mislead callers.

Source

Thrown at kernel/model/attribute_view.go:7133

		return &TxErr{code: TxErrHandleAttributeView, id: operation.AvID, msg: err.Error()}
	}
	return
}

func setAttributeViewColDateFormat(operation *Operation) (err error) {
	format := av.DateDisplayFormat(operation.Format)
	if !format.IsValid() {
		return errors.New("invalid date display format")
	}

	attrView, err := av.ParseAttributeView(operation.AvID)
	if err != nil {
		return
	}

	colType := av.KeyType(operation.Typ)
	if av.KeyTypeDate != colType && av.KeyTypeCreated != colType && av.KeyTypeUpdated != colType {
		return errors.New("date display format is only available for date fields")
	}
	for _, keyValues := range attrView.KeyValues {
		if keyValues.Key.ID == operation.ID && keyValues.Key.Type == colType {
			keyValues.Key.DateFormat = format
			break
		}
	}

	err = av.SaveAttributeView(attrView)
	return
}

func (tx *Transaction) doUpdateAttrViewColumn(operation *Operation) (ret *TxErr) {
	err := updateAttributeViewColumn(operation)
	if err != nil {
		return &TxErr{code: TxErrHandleAttributeView, id: operation.AvID, msg: err.Error()}
	}
	return

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Only invoke setAttrViewColDateFormat when the target column's type is date, created, or updated; read the current type first.
  2. After retyping a column, clear pending format-change operations on the client so they do not fire against the new type.
  3. Guard the UI: hide the date-format control for non-date columns.

Example fix

// before
setAttributeViewColDateFormat({ avID, id: colID, typ: 'text', format })
// after
const col = getAttrViewKey(avID, colID)
if (!['date','created','updated'].includes(col.type)) return
setAttributeViewColDateFormat({ avID, id: colID, typ: col.type, format })
Defensive patterns

Strategy: type-guard

Validate before calling

const col = (await getAttrViewKeys(avID)).find(k => k.id === op.id)
if (!col || !['date','created','updated'].includes(col.type)) { /* skip date-format op for non-date column */ }

Type guard

type DateLikeType = 'date' | 'created' | 'updated'
function isDateLikeType(t: string): t is DateLikeType { return t === 'date' || t === 'created' || t === 'updated' }

Prevention

When it happens

Trigger: Sending a setAttrViewColDateFormat operation against a non-date column — e.g. the UI dispatched the format change against the wrong column ID, or a column was retyped from date to text but a stale format operation still fired.

Common situations: Frontend state desync after a column type change; copy-paste of an operation with a stale typ; a script that applies the same format to every column indiscriminately.

Related errors


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