siyuan-note/siyuan · error

clone attribute view value

Error message

clone attribute view value [%s] failed

What it means

This error is returned when cloning an existing attribute view (database) row value fails during batch cell updates. Before applying new cell data, the transaction reads the current row value for the row ID and calls Value.Clone(); if the clone returns nil the transaction aborts, because continuing would mutate shared state and corrupt the database value cache.

Solutions

  1. Refresh/reindex the affected notebook (rebuild database index) so GetBlockValue returns fully populated values
  2. Verify each cell.RowID in the request corresponds to a real, currently bound row in the attribute view before calling the API
  3. Update SiYuan to a version with a fixed av.Value.Clone implementation if you can reproduce with a valid row
  4. Re-create the affected database row (detach and re-bind the block) to replace the corrupt value record

Example fix

// before
cells := [{rowID: 'stale-or-fake-id', ...}]
api.batchUpdateAttrViewCell(cells)
// after
const row = av.rows.find(r => r.id === cell.rowID)
if (!row) throw new Error('row not bound')
api.batchUpdateAttrViewCell(cells)
Defensive patterns

Strategy: validation

Validate before calling

const original = av.blockValues && av.blockValues[cell.rowID];
if (!original || !original.id) throw new Error('row ' + cell.rowID + ' has no bindable value');

Type guard

function isBindableRow(v) {
  return !!v && typeof v.id === 'string' && v.id !== '' && !!v.block;
}

Prevention

When it happens

Trigger: Calling UpdateAttrViewCells or BatchUpdateAttributeViewCells (kernel API updateAttrViewCell / batchUpdateAttrViewCell) where preflightAttributeViewCellBindings finds a row value via GetBlockValue(cell.RowID) whose Clone() yields nil — typically a zero-value or partially initialized av.Value whose underlying Block/map state cannot be safely deep-copied.

Common situations: Historic or index-degraded database rows whose value structs lack the expected sub-objects; concurrent transactions mutated the attribute view between read and clone; programmatic callers passing stale or fabricated row IDs built outside the normal binding flow.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/e25ebfb38cbbbd63. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/attribute_view_binding.go:35

		return nil
	}
	values := map[string]*av.Value{}
	for _, cell := range cells {
		if cell == nil {
			return av.ErrKeyNotFound
		}
		if cell.KeyID != key.ID {
			continue
		}
		value := values[cell.RowID]
		if value == nil {
			original := attrView.GetBlockValue(cell.RowID)
			if original == nil {
				return av.ErrItemNotFound
			}
			value = original.Clone()
			if value == nil {
				return fmt.Errorf("clone attribute view value [%s] failed", original.ID)
			}
			values[cell.RowID] = value
		}
		data, err := gulu.JSON.MarshalJSON(cell.Data)
		if err != nil {
			return err
		}
		if err = gulu.JSON.UnmarshalJSON(data, value); err != nil {
			return err
		}
		if !value.IsDetached {
			if value.Block == nil {
				return ErrBlockNotFound
			}
			_, tree, loadErr := getNodeByBlockID(tx, value.Block.ID)
			if loadErr != nil {
				return loadErr
			}

View on GitHub (pinned to 9f775e8a12)