{"record":{"id":"2f918ffb11a44a7c","repo":"swc-project/swc","slug":"property-symbol-dispose-is-not-a-function-2f918f","errorCode":null,"errorMessage":"Property [Symbol.dispose] is not a function.","messagePattern":"Property \\[Symbol\\.dispose\\] is not a function\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"crates/swc_ecma_transforms_base/src/helpers/generated/_using_ctx.rs","lineNumber":36,"sourceCode":"                err.error = error;\n                return err;\n            }),\n        empty = {},\n        stack = [];\n    function using(isAwait, value) {\n        if (value != null) {\n            if (Object(value) !== value) {\n                throw new TypeError(\"using declarations can only be used with objects, functions, null, or undefined.\");\n            }\n            // core-js-pure uses Symbol.for for polyfilling well-known symbols\n            if (isAwait) {\n                var dispose = value[Symbol.asyncDispose || Symbol.for(\"Symbol.asyncDispose\")];\n            }\n            if (dispose == null) {\n                dispose = value[Symbol.dispose || Symbol.for(\"Symbol.dispose\")];\n            }\n            if (typeof dispose !== \"function\") {\n                throw new TypeError(`Property [Symbol.dispose] is not a function.`);\n            }\n            stack.push({ v: value, d: dispose, a: isAwait });\n        } else if (isAwait) {\n            // provide the nullish `value` as `d` for minification gain\n            stack.push({ d: value, a: isAwait });\n        }\n        return value;\n    }\n    return {\n        // error\n        e: empty,\n        // using\n        u: using.bind(null, false),\n        // await using\n        a: using.bind(null, true),\n        // dispose\n        d: function() {\n            var error = this.e;","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_ecma_transforms_base/src/helpers/generated/_using_ctx.rs#L18-L54","documentation":"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.`","triggerScenarios":"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.","commonSituations":"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.","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'`."],"exampleFix":"// before\n{\n  using pool = createPool(); // createPool exposes .destroy()\n  // TypeError: Property [Symbol.dispose] is not a function.\n}\n\n// after\nconst pool = createPool();\npool[Symbol.dispose] ??= () => pool.destroy();\n{\n  using p = pool;\n}","handlingStrategy":"type-guard","validationCode":"// Ensure each resource exposes a callable dispose before the block.\nconst disposeKey = Symbol.dispose || Symbol.for('Symbol.dispose');\nfor (const r of resources) {\n  if (r != null && typeof r[disposeKey] !== 'function') {\n    r[disposeKey] = () => r.close();\n  }\n}","typeGuard":"const isDisposable = (v: unknown): v is Disposable =>\n  v != null &&\n  (typeof v === 'object' || typeof v === 'function') &&\n  typeof (v as Record<symbol, unknown>)[Symbol.dispose ?? Symbol.for('Symbol.dispose')] === 'function';","tryCatchPattern":null,"preventionTips":["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."],"tags":["using-declaration","using-ctx","symbol-dispose","disposable"],"backgroundTag":"dispose-not-a-function","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}