siyuan-note/siyuan · error

invalid card cover position

Error message

invalid card cover position [%v, %v]

What it means

The cover position X/Y coordinates must be finite numbers in the inclusive range 0..100 (percent). NaN, +/-Inf, negative values, or values above 100 raise this error. It keeps the stored cover focal point a valid percentage.

Solutions

  1. Clamp x and y into [0, 100] before building the operation (Math.min(100, Math.max(0, value))).
  2. Guard against NaN/Infinity from division: check the denominator before computing the percentage.
  3. Convert pixel offsets to percentages of the image size before sending.

Example fix

// before
const x = offsetX / width * 100; // width may be 0 -> NaN
// after
const x = width > 0 ? Math.min(100, Math.max(0, offsetX / width * 100)) : 50;
Defensive patterns

Strategy: validation

Validate before calling

const clampPct = (n) => Math.min(100, Math.max(0, n));
if (!Number.isFinite(position.x) || !Number.isFinite(position.y)) throw new Error("position must be finite");

Type guard

const isPercent = (v: unknown): v is number => typeof v === "number" && Number.isFinite(v) && v >= 0 && v <= 100;

Try / catch

try { await setCardCoverPosition(...); } catch (e) { if (String(e).includes("invalid card cover position")) retryWithClampedPosition(); else throw e; }

Prevention

When it happens

Trigger: doSetAttrViewCardCoverPosition with data.position.x or .y being NaN/Infinity (e.g. from a JS division by zero) or outside 0-100, such as -5 or 150.

Common situations: Drag-position UI math producing NaN when element dimensions are zero; percent-to-pixel conversion bugs; clients passing raw pixel offsets instead of percentages.

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/2fa3d174f9876488. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/attribute_view.go:2070

	dataJSON, err := json.Marshal(operation.Data)
	if nil != err {
		return
	}
	var data setAttrViewCardCoverPositionData
	if err = json.Unmarshal(dataJSON, &data); nil != err {
		return
	}
	if !av.IsValidCardCoverSource(data.Source) {
		return fmt.Errorf("invalid card cover source [%s]", data.Source)
	}
	if nil != data.Position {
		if "" == data.Position.Image || 32*1024 < len(data.Position.Image) {
			return errors.New("invalid card cover image")
		}
		if math.IsNaN(data.Position.X) || math.IsInf(data.Position.X, 0) ||
			math.IsNaN(data.Position.Y) || math.IsInf(data.Position.Y, 0) ||
			data.Position.X < 0 || 100 < data.Position.X || data.Position.Y < 0 || 100 < data.Position.Y {
			return fmt.Errorf("invalid card cover position [%v, %v]", data.Position.X, data.Position.Y)
		}
	}

	attrView, err := av.ParseAttributeView(operation.AvID)
	if nil != err {
		return
	}
	if nil == attrView.GetBlockValue(operation.RowID) {
		return fmt.Errorf("attribute view item [%s] not found", operation.RowID)
	}
	view, err := getAttrViewViewByBlockID(attrView, operation.BlockID)
	if nil != err {
		return
	}
	if av.LayoutTypeGallery != view.LayoutType && av.LayoutTypeKanban != view.LayoutType {
		return av.ErrWrongLayoutType
	}
	var source string

View on GitHub (pinned to 9f775e8a12)