BabylonJS/Babylon.js · error

Deleting persistent anchors is not supported in this environ

Error message

Deleting persistent anchors is not supported in this environment/browser

What it means

WebXR persistent anchors let anchors survive sessions, but the API (XRSession.deletePersistentAnchor) is only available in browsers/runtimes that implemented the persistent-anchors extension. Babylon's WebXRAnchorSystem checks for the method on the active XRSession and throws this Error when it is absent, instead of failing silently. It means you attempted to delete a stored anchor in an environment that cannot support persistent anchor deletion.

Source

Thrown at packages/dev/core/src/XR/features/WebXRAnchorSystem.pure.ts:383

     * Restore all persistent anchors known to the current XR session
     * @returns A promise that resolves after all restored anchors are tracked by an XR frame
     * @throws If persistent anchor enumeration or restoration is not supported by the current session
     */
    public async restorePersistentAnchorsAsync(): Promise<IWebXRAnchor[]> {
        return await Promise.all(this.persistentAnchors.map(async (handle) => await this.restorePersistentAnchorAsync(handle)));
    }

    /**
     * Delete a persistent anchor from native storage
     * @param handle The persistent anchor handle to delete
     * @returns A promise that resolves after native persistent storage is deleted
     * @throws If deleting persistent anchors is not supported by the current session
     */
    public async deletePersistentAnchorAsync(handle: string): Promise<void> {
        const session = this._xrSessionManager.session;
        const deletePersistentAnchor = session?.deletePersistentAnchor;
        if (!deletePersistentAnchor) {
            throw new Error("Deleting persistent anchors is not supported in this environment/browser");
        }

        await deletePersistentAnchor.call(session, handle);
        for (const anchor of this._trackedAnchors) {
            if (anchor.persistentHandle === handle) {
                anchor._removed = true;
            }
        }
        for (const futureAnchor of this._futureAnchors) {
            if (!futureAnchor.resolved && futureAnchor.persistentHandle === handle) {
                futureAnchor.resolved = true;
                futureAnchor.reject(new Error("The persistent anchor was deleted before tracking began"));
            }
        }
    }

    /**
     * detach this feature.

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Feature-detect support before calling: check `xrSessionManager.session?.deletePersistentAnchor` and gate your delete UI/flow on it.
  2. Ensure persistent anchors are requested when creating the session (e.g. requiredFeatures/options for anchors with persistent support) and use a browser that implements them.
  3. Wrap the call in try/catch and degrade gracefully (e.g. hide persistent anchors, inform the user) when the API is missing.
  4. Update the device's browser/OS to a version that implements WebXR persistent anchors.

Example fix

// before
await anchors.deletePersistentAnchorAsync(handle);
// after
const session = xrSessionManager.session;
if (typeof session?.deletePersistentAnchor === "function") {
    await anchors.deletePersistentAnchorAsync(handle);
} else {
    console.warn("Persistent anchor deletion not supported here");
}
Defensive patterns

Strategy: type-guard

Validate before calling

const canDelete = typeof xrSessionManager.session?.deletePersistentAnchor === "function";
if (!canDelete) { /* hide delete UI or use fallback */ }

Type guard

function supportsPersistentAnchorDelete(session: XRSession | undefined): session is XRSession & { deletePersistentAnchor: (handle: string) => Promise<void> } {
    return typeof session?.deletePersistentAnchor === "function";
}

Try / catch

try {
    await anchors.deletePersistentAnchorAsync(handle);
} catch (e) {
    if (String((e as Error).message).includes("not supported")) {
    console.warn("Persistent anchor deletion unavailable");
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling xrFeature.deletePersistentAnchorAsync(handle) on a session whose XRSession object has no deletePersistentAnchor function (browser lacking the persistent anchors capability or a session not requested with the required feature descriptors).

Common situations: Testing on desktop browsers or headsets/OS versions where anchors-modal/persistent-anchors is unsupported; forgetting that persistent anchors require explicit session feature request; running older WebXR runtimes (e.g. older Oculus/Quest browser) that never shipped deletePersistentAnchor.

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/57be26e4c2dc76c9. Report an issue: GitHub.