toeverything/AFFiNE · error · BlockSuiteError

ValueNotExists

ValueNotExists

Error message

Failed to get start and end points when getting connectable points

What it means

While computing connectable points for a connector, the function searches the collected points list for nextStartPoint and lastEndPoint within an almostEqual tolerance of 0.02. If either cannot be found in the list it throws ValueNotExists — the routing geometry is inconsistent and the endpoints are not among the candidate points.

Source

Thrown at blocksuite/affine/gfx/connector/src/connector-manager.ts:569

  points = removeDulicatePoints(points);

  const sorted = points.map(point => point[0] + ',' + point[1]).sort();
  sorted.forEach((cur, index) => {
    if (index === 0) return;
    if (cur === sorted[index - 1]) {
      throw new Error('duplicate point');
    }
  });
  const startEnds = [nextStartPoint, lastEndPoint].map(point => {
    return points.find(
      item =>
        almostEqual(item[0], point[0], 0.02) &&
        almostEqual(item[1], point[1], 0.02)
    );
  });
  if (!startEnds[0] || !startEnds[1]) {
    throw new BlockSuiteError(
      BlockSuiteError.ErrorCode.ValueNotExists,
      'Failed to get start and end points when getting connectable points'
    );
  }
  return { points, nextStartPoint: startEnds[0], lastEndPoint: startEnds[1] };
}

function getDirectPath(startPoint: IVec, endPoint: IVec): IVec[] {
  if (
    almostEqual(startPoint[0], endPoint[0], 0.02) ||
    almostEqual(startPoint[1], endPoint[1], 0.02)
  ) {
    return [startPoint, endPoint];
  } else {
    const vec = Vec.sub(endPoint, startPoint);
    const mid: IVec = [startPoint[0], startPoint[1] + vec[1]];
    return [startPoint, mid, endPoint];
  }

View on GitHub (pinned to 26c515e050)

Solutions

  1. Verify the connected elements have non-zero bounds before routing.
  2. Loosen or centrally define the almostEqual tolerance if drift is expected.
  3. Guard connectable-points callers and fall back to a direct path when this throws.
Defensive patterns

Strategy: try-catch

Validate before calling

function hasNonZeroBound(el: GfxElement): boolean { const b = el.externalBound ?? el.elementBound; return b.w > 0 && b.h > 0; }

Try / catch

try { return getConnectablePoints(...); } catch (e) { if (e instanceof BlockSuiteError && e.code === BlockSuiteError.ErrorCode.ValueNotExists) { return getDirectPath(start, end); } throw e; }

Prevention

When it happens

Trigger: Connector routing where the start/end anchors produce points that, after de-duplication and bound expansion, no longer match any candidate vertex/midpoint within tolerance.

Common situations: Zero-size or degenerate element bounds; nested/rotated connectors; floating-point drift between anchor and bound computations; overlapping elements.

Related errors


AI-assisted analysis of toeverything/AFFiNE@26c515e050 (2026-08-12). Data as JSON: /api/errors/b41c28261e8387fd. Report an issue: GitHub.