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
- Stop enumerating or serializing the instance after its dispose/cleanup was invoked.
- Capture the needed data (keys, snapshot) before teardown instead of after.
- 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
- Snapshot data (keys, values) you need before calling dispose().
- Skip serialization/logging of internals once teardown has started.
- Set disposed references to null and check before spreading or stringify-ing them.
- Use structured logging of explicit fields rather than dumping whole objects.
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
- Cannot call method on ${instanceName}. The '${name}' has bee
- Cannot check property existence on ${instanceName}. The '${n
- Cannot get prototype of ${instanceName}. The '${name}' has b
- Warehouse is being deleted (current state: ${data.state})
- CubeServer is already listening
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/e77afdae30a04c3d.
Report an issue: GitHub.