swc-project/swc · error · TypeError
Property [Symbol.dispose] is not a function.
Error message
Property [Symbol.dispose] is not a function.
What it means
In `_using`, after the resource passes the object check, the helper resolves its disposal method via `value[Symbol.dispose]` (falling back to the `Symbol.for` polyfill key) and requires it to be callable. Otherwise it throws `TypeError: Property [Symbol.dispose] is not a function.`
Source
Thrown at crates/swc_ecma_transforms_base/src/helpers/generated/_using.rs:25
local: "_using",
import_path: "@swc/helpers/_/_using",
#[cfg(feature = "inline-helpers")]
source: r#"/* @minVersion 7.22.0 */
function _using(stack, value, isAwait) {
if (value === null || value === void 0) return value;
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 === void 0) {
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 });
return value;
}
"#,
#[cfg(feature = "inline-helpers")]
deps: super::HelperBitmap::from_bits(0x00000010000000000000000000000000),
};
#[cfg(feature = "inline-helpers")]
pub fn stmts() -> &'static [swc_ecma_ast::Stmt] {
static STMTS: once_cell::sync::Lazy<Vec<swc_ecma_ast::Stmt>> =
once_cell::sync::Lazy::new(|| super::super::parse(DEF.source, DEF.import_path));
&STMTS
}
View on GitHub (pinned to 5176682b65)
Solutions
- Give the resource a symbol-keyed method: `res[Symbol.dispose] = () => res.close();` before the `using` statement.
- Create an adapter object with `[Symbol.dispose]` that delegates to the library's close/release method.
- Verify disposability up front: `typeof res[Symbol.dispose] === 'function'`.
- On runtimes without `Symbol.dispose`, polyfill the symbol and attach methods under that same key.
Example fix
// before
using conn = await db.connect(); // only has conn.close()
// TypeError: Property [Symbol.dispose] is not a function.
// after
const conn = await db.connect();
using guarded = Object.create(conn, { [Symbol.dispose]: { value: () => conn.close() } });
// or: conn[Symbol.dispose] ??= () => conn.close(); using guarded = conn; Defensive patterns
Strategy: type-guard
Validate before calling
// Confirm a callable dispose (or asyncDispose) before the using block.
const hasDisposeMethod = (v) => {
if (v == null) return true;
const key = Symbol.dispose || Symbol.for('Symbol.dispose');
return typeof v[key] === 'function';
};
if (!hasDisposeMethod(res)) res[Symbol.dispose] = () => res.close(); Type guard
const isDisposable = (v: unknown): v is Disposable =>
v != null &&
(typeof v === 'object' || typeof v === 'function') &&
typeof (v as Disposable)[Symbol.dispose ?? Symbol.for('Symbol.dispose')] === 'function'; Prevention
- Use the symbol key `[Symbol.dispose]`, never a string method name, when making wrappers disposable.
- Centralize adapter creation (`toDisposable(res, r => r.close())`) so every resource goes through one checked path.
- On polyfilled runtimes, register the fallback key consistently via `Symbol.for('Symbol.dispose')`.
When it happens
Trigger: `using x = someObject;` where `someObject` has no `[Symbol.dispose]` method, or where the property exists but is not callable (null, number, string-keyed `dispose` instead of the symbol key).
Common situations: Wrapping third-party resources (DB connections, file handles) that only have a `.close()`/`.dispose()` method; test stubs without the symbol method; assuming `await using`-style async methods satisfy sync `using`.
Related errors
- Object not disposable.
- Object expected.
- Symbol.dispose is not defined.
- using declarations can only be used with objects, functions,
- Property [Symbol.dispose] is not a function.
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/725cbd69e6255127.
Report an issue: GitHub.