siyuan-note/siyuan · error

invalid paste row count

Error message

invalid paste row count [%d]

What it means

getAttributeViewPasteRowsFromTable validates that the requested paste row count is at least 1 before slicing table rows. A count below 1 cannot produce a meaningful slice, so it returns this error immediately.

Solutions

  1. Ensure count >= 1 before calling; return early on empty clipboard instead of invoking the API
  2. Fix the clipboard row-count computation so empty pastes are short-circuited upstream
  3. Clamp: if parsed rows is empty, skip the paste entirely rather than requesting 0 rows

Example fix

// before
rows, err := getAttributeViewPasteRowsFromTable(table, startID, len(parsedRows))
// after
if len(parsedRows) == 0 { return nil } // nothing to paste
rows, err := getAttributeViewPasteRowsFromTable(table, startID, len(parsedRows))
Defensive patterns

Strategy: validation

Validate before calling

if (!Number.isInteger(count) || count < 1) { throw new Error(`invalid paste row count ${count}`) }

Try / catch

rows, err := getAttributeViewPasteRowsFromTable(table, startID, count)
if err != nil && strings.Contains(err.Error(), "invalid paste row count") {
    return ErrNothingToPaste
}

Prevention

When it happens

Trigger: Calling GetAttributeViewPasteRows (directly or via TestGetAttributeViewPasteRowsFromTable) with count <= 0 — e.g. clipboard reported zero rows, or an off-by-one in computing rows-to-paste.

Common situations: Pasting an empty clipboard selection; frontend computing row count from an empty parsed clipboard table; passing 0 as a default that was never initialized.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at kernel/model/attribute_view_render.go:386

	ret = map[string]struct{}{}
	for _, attrView := range attrViews {
		if nil == attrView {
			continue
		}
		for _, keyValues := range attrView.KeyValues {
			if nil == keyValues || nil == keyValues.Key || av.KeyTypeRollup != keyValues.Key.Type ||
				nil == keyValues.Key.Rollup || "" == keyValues.Key.Rollup.KeyID {
				continue
			}
			ret[keyValues.Key.Rollup.KeyID] = struct{}{}
		}
	}
	return
}

func getAttributeViewPasteRowsFromTable(table *av.Table, startItemID string, count int) (rows []*av.TableRow, err error) {
	if count < 1 {
		return nil, fmt.Errorf("invalid paste row count [%d]", count)
	}
	start := -1
	for i, row := range table.Rows {
		if row.ID == startItemID {
			start = i
			break
		}
	}
	if 0 > start {
		return nil, fmt.Errorf("attribute view item [%s] not found", startItemID)
	}
	end := start + min(count, len(table.Rows)-start)
	return table.Rows[start:end], nil
}

func RenderAttributeViewWithTarget(blockID, avID, viewID, query string, page, pageSize int, groupPaging map[string]any, initialLayout av.LayoutType, createIfNotExist, ignoreRows bool, targetItemID, targetGroupID string) (viewable av.Viewable, attrView *av.AttributeView, target *AttributeViewRenderTarget, err error) {
	if !ast.IsNodeIDPattern(avID) {
		err = ErrInvalidID

View on GitHub (pinned to 9f775e8a12)