swc-project/swc · error · TypeError
Property [Symbol.dispose] is not a function.
Error message
Property [Symbol.dispose] is not a function.
What it means
Inside `_using_ctx`'s `using(isAwait, value)` function, once the resource passes the object check the helper resolves `value[Symbol.dispose]` (with the `Symbol.for` polyfill-key fallback) and requires a function. A missing or non-callable dispose method throws `TypeError: Property [Symbol.dispose] is not a function.`
Source
Thrown at crates/swc_ecma_transforms_base/src/helpers/generated/_using_ctx.rs:36
err.error = error;
return err;
}),
empty = {},
stack = [];
function using(isAwait, value) {
if (value != null) {
if (Object(value) !== value) {
throw new TypeError("using declarations can only be used with objects, functions, null, or undefined.");
}
// core-js-pure uses Symbol.for for polyfilling well-known symbols
if (isAwait) {
var dispose = value[Symbol.asyncDispose || Symbol.for("Symbol.asyncDispose")];
}
if (dispose == null) {
dispose = value[Symbol.dispose || Symbol.for("Symbol.dispose")];
}
if (typeof dispose !== "function") {
throw new TypeError(`Property [Symbol.dispose] is not a function.`);
}
stack.push({ v: value, d: dispose, a: isAwait });
} else if (isAwait) {
// provide the nullish `value` as `d` for minification gain
stack.push({ d: value, a: isAwait });
}
return value;
}
return {
// error
e: empty,
// using
u: using.bind(null, false),
// await using
a: using.bind(null, true),
// dispose
d: function() {
var error = this.e;View on GitHub (pinned to 5176682b65)
Solutions
- Attach the symbol method before the block: `res[Symbol.dispose] ??= () => res.release();`.
- Wrap the resource in a disposable adapter whose `[Symbol.dispose]` calls the library method.
- Polyfill `Symbol.dispose` at startup so resources and helper use the same key.
- Pre-check disposability: `typeof res?.[Symbol.dispose] === 'function'`.
Example fix
// before
{
using pool = createPool(); // createPool exposes .destroy()
// TypeError: Property [Symbol.dispose] is not a function.
}
// after
const pool = createPool();
pool[Symbol.dispose] ??= () => pool.destroy();
{
using p = pool;
} Defensive patterns
Strategy: type-guard
Validate before calling
// Ensure each resource exposes a callable dispose before the block.
const disposeKey = Symbol.dispose || Symbol.for('Symbol.dispose');
for (const r of resources) {
if (r != null && typeof r[disposeKey] !== 'function') {
r[disposeKey] = () => r.close();
}
} Type guard
const isDisposable = (v: unknown): v is Disposable =>
v != null &&
(typeof v === 'object' || typeof v === 'function') &&
typeof (v as Record<symbol, unknown>)[Symbol.dispose ?? Symbol.for('Symbol.dispose')] === 'function'; Prevention
- Standardize one `withDisposable(res, releaseFn)` helper that attaches `[Symbol.dispose]` for every third-party resource.
- When polyfilling the symbol, use the same `Symbol.for` key in both the polyfill and resource adapters.
- Unit-test the dispose path of each adapter — a non-function method fails only when the block exits.
When it happens
Trigger: A resource in a `using` block (compiled to the ctx helper) that lacks `[Symbol.dispose]` — e.g. it only exposes `.close()`, `.release()`, or a string-keyed `dispose` — or where the symbol-keyed property is set to a non-function.
Common situations: Wrapping connection pools, file descriptors, or mutexes that use library-specific release methods; polyfilled environments where the resource and the helper disagree on which symbol key identifies dispose.
Related errors
- Object not disposable.
- Property [Symbol.dispose] is not a function.
- Object expected.
- Symbol.dispose is not defined.
- using declarations can only be used with objects, functions,
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/2f918ffb11a44a7c.
Report an issue: GitHub.