siyuan-note/siyuan · error · TypeError

The range must be inside one editable source block of this P

Error message

The range must be inside one editable source block of this Protyle instance

What it means

trackRange precondition: the given DOM Range does not lie entirely inside a single editable source block of the passed Protyle instance. Range tracking is per editable block, so a range spanning blocks, in a different editor, or outside editable content is rejected.

Source

Thrown at app/src/protyle/util/trackedRange.ts:1147

};

export const trackRange = (protyle: IProtyle, range: Range,
                           options: ITrackRangeOptions): ITrackedRangeHandle => {
    if (destroyedProtyles.has(protyle)) {
        throw new Error("Cannot track a range in a destroyed Protyle instance");
    }
    if (!options?.owner || !["function", "object"].includes(typeof options.owner)) {
        throw new TypeError("The tracked range owner is required");
    }
    if (options.affinity && !["after", "before"].includes(options.affinity)) {
        throw new TypeError("The tracked range affinity must be before or after");
    }
    if (unloadingPlugins.has(options.owner)) {
        throw new Error("Cannot track a range for an unloaded plugin");
    }
    const rangeSnapshot = getRangeSnapshot(protyle, range);
    if (!rangeSnapshot) {
        throw new TypeError("The range must be inside one editable source block of this Protyle instance");
    }
    const targetTokens = rangeSnapshot.stream.tokens.slice(rangeSnapshot.start, rangeSnapshot.end);
    if (!range.collapsed && targetTokens.length === 0) {
        throw new TypeError("The tracked range must contain semantic content");
    }
    const handle = Object.freeze({id: `tracked-range-${++handleSequence}`});
    const trackedRange = range.cloneRange();
    const state: ITrackedRangeState = {
        range: trackedRange,
        startContainer: trackedRange.startContainer,
        endContainer: trackedRange.endContainer,
        exactTarget: getExactlySelectedElement(trackedRange),
        collapsed: trackedRange.collapsed,
        affinity: options.affinity || "before",
        targetTokens,
        tokens: rangeSnapshot.stream.tokens,
        start: rangeSnapshot.start,
        end: rangeSnapshot.end,

View on GitHub (pinned to 8641553a1f)

Solutions

  1. Narrow the range to one editable block element before tracking
  2. Verify the range was obtained from the same Protyle instance
  3. Re-create the range from saved anchor offsets inside one block
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at app/src/protyle/util/trackedRange.ts:1147 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11). Data as JSON: /api/errors/0936629bb294a7c3. Report an issue: GitHub.