cube-js/cube · error · Error

Cannot call method on

Error message

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

What it means

Cube replaces disposed internal objects with a proxy from disposedProxy() that throws on any interaction. The `apply` trap fires when the proxy is invoked as a function, meaning code held a reference to a method/object belonging to something that has already been cleaned up (e.g. a disposed queue, orchestrator, or driver). It is a deliberate safeguard to surface dangling references after teardown instead of failing silently or crashing obscurely.

Solutions

  1. Find what created the disposed instance and stop using references to it after its dispose/cleanup was called.
  2. Re-acquire the instance from the live server/orchestrator instead of caching it at startup.
  3. Cancel pending timers, listeners, or in-flight async work during teardown so they never invoke the disposed object.
  4. Guard usage with a liveness check or wrap the call in try/catch to handle races during shutdown.

Example fix

// before
const queue = server.queryQueue;
server.dispose();
setTimeout(() => queue.execute(query), 1000); // throws

// after
let queue = server.queryQueue;
server.dispose();
queue = null;
setTimeout(() => { if (queue) queue.execute(query); }, 1000);
Defensive patterns

Strategy: try-catch

Validate before calling

if (instanceRef === null || instanceRef === undefined) {
  throw new Error('Reference already disposed; re-acquire it.');
}
const probe = {};
try {
  // liveness probe: disposed proxy throws on 'has'
  'anything' in instanceRef;
} catch (e) {
  throw new Error('Instance was disposed, do not call methods on it.');
}

Type guard

function isAlive<T extends object>(ref: T | null | undefined): ref is T {
  if (ref == null) return false;
  try {
    'livenessProbe' in ref;
    return true;
  } catch {
    return false;
  }
}

Try / catch

try {
  disposedInstance.someMethod();
} catch (e) {
  if (e.message.includes('has been cleaned up and is no longer available')) {
    // re-acquire a live instance or abort the in-flight work
    instanceRef = null;
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling a method on an instance whose owner was disposed via its cleanup/dispose path, so the property now resolves to the disposed proxy. E.g. keeping a reference to an orchestrator's queryQueue and invoking it after the server was shut down.

Common situations: Holding long-lived references to Cube internals across server restarts or hot reloads; calling a method asynchronously after the instance's dispose() already ran (a pending setTimeout, promise chain, or event listener); unit tests reusing captured references between test cases.

Related errors


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

Appendix: source

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

 * Creates a proxy object that throws an error on any property access.
 * Used as a safeguard after disposal to catch dangling references.
 */
export function disposedProxy(name: string, instanceName: string): any {
  return new Proxy({}, {
    get(_target: object, prop: string | symbol): never {
      throw new Error(
        `Cannot access property '${String(prop)}' on ${instanceName}. ` +
        `The '${name}' has been cleaned up and is no longer available.`
      );
    },
    set(_target: object, prop: string | symbol): never {
      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(

View on GitHub (pinned to 7d981676b3)