cube-js/cube · error · Error

Cannot enumerate properties on ${instanceName}. The '${name}

Error message

Cannot enumerate properties on ${instanceName}. The '${name}' has been cleaned up and is no longer available.

What it means

The `ownKeys` trap of the disposed proxy fires when code enumerates the properties of an instance that Cube has already disposed (e.g. via Object.keys, spread, JSON.stringify, or for...in). Cube throws deliberately to catch references that outlived their owner's cleanup.

Source

Thrown at packages/cubejs-backend-shared/src/disposedProxy.ts:32

      throw new Error(
        `Cannot set property '${String(prop)}' on ${instanceName}. ` +
        `The '${name}' has been cleaned up and is no longer available.`
      );
    },
    apply(): never {
      throw new Error(
        `Cannot call method on ${instanceName}. ` +
        `The '${name}' has been cleaned up and is no longer available.`
      );
    },
    has(_target: object, _prop: string | symbol): never {
      throw new Error(
        `Cannot check property existence on ${instanceName}. ` +
        `The '${name}' has been cleaned up and is no longer available.`
      );
    },
    ownKeys(): never {
      throw new Error(
        `Cannot enumerate properties on ${instanceName}. ` +
        `The '${name}' has been cleaned up and is no longer available.`
      );
    },
    getPrototypeOf(): never {
      throw new Error(
        `Cannot get prototype of ${instanceName}. ` +
        `The '${name}' has been cleaned up and is no longer available.`
      );
    }
  });
}

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Stop enumerating or serializing the instance after its dispose/cleanup was invoked.
  2. Capture the needed data (keys, snapshot) before teardown instead of after.
  3. Clear stale references on disposal and check for null before enumerating.

Example fix

// before
server.dispose();
console.log(Object.keys(server.dataSourceStorage)); // throws

// after
const keys = Object.keys(server.dataSourceStorage);
server.dispose();
console.log(keys);
Defensive patterns

Strategy: try-catch

Validate before calling

if (objRef == null) {
  throw new Error('Cannot enumerate a cleared reference.');
}

Type guard

function isEnumerable<T extends object>(ref: T | null | undefined): ref is T {
  if (ref == null) return false;
  try {
    Object.keys(ref);
    return true;
  } catch {
    return false;
  }
}

Try / catch

let keys: string[];
try {
  keys = Object.keys(maybeDisposed);
} catch (e) {
  if (e.message.includes('has been cleaned up')) {
    keys = []; // or skip serialization entirely
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Running Object.keys()/Object.entries()/Object.assign()/JSON.stringify()/for...in over an object whose owning instance was disposed, so it is backed by the disposed proxy.

Common situations: Serializing or logging Cube internals (drivers, queues) after shutdown; spreading a stale reference into a new object; debugging code that inspects a disposed instance's shape.

Related errors


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/e77afdae30a04c3d. Report an issue: GitHub.