{"record":{"id":"6c0c386e3fef55bf","repo":"swc-project/swc","slug":"symbol-asyncdispose-is-not-defined","errorCode":null,"errorMessage":"Symbol.asyncDispose is not defined.","messagePattern":"Symbol\\.asyncDispose is not defined\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"crates/swc_ecma_transforms_base/src/helpers/generated/_ts_add_disposable_resource.rs","lineNumber":18,"sourceCode":"// This file is generated by `cargo codegen helpers`. DO NOT MODIFY.\n\nuse super::{HelperDef, HelperName};\n\npub const DEF: HelperDef = HelperDef {\n    name: HelperName::ts_add_disposable_resource,\n    local: \"_ts_add_disposable_resource\",\n    import_path: \"@swc/helpers/_/_ts_add_disposable_resource\",\n    #[cfg(feature = \"inline-helpers\")]\n    source: r#\"function _ts_add_disposable_resource(env, value, async) {\n    if (value !== null && value !== void 0) {\n        if (typeof value !== \"object\" && typeof value !== \"function\") {\n            throw new TypeError(\"Object expected.\");\n        }\n        var dispose, inner;\n        if (async) {\n            if (!Symbol.asyncDispose) {\n                throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n            }\n            dispose = value[Symbol.asyncDispose];\n        }\n        if (dispose === void 0) {\n            if (!Symbol.dispose) {\n                throw new TypeError(\"Symbol.dispose is not defined.\");\n            }\n            dispose = value[Symbol.dispose];\n            if (async) {\n                inner = dispose;\n            }\n        }\n        if (typeof dispose !== \"function\") {\n            throw new TypeError(\"Object not disposable.\");\n        }\n        if (inner) {\n            dispose = function() {\n                try {","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_ecma_transforms_base/src/helpers/generated/_ts_add_disposable_resource.rs#L1-L36","documentation":"In the same `_ts_add_disposable_resource` helper, `await using` requires the well-known symbol `Symbol.asyncDispose`. The downlevel helper does not polyfill it; if the runtime lacks the symbol it throws `TypeError(\"Symbol.asyncDispose is not defined.\")` before even reading the method off the value.","triggerScenarios":"`await using x = res;` executed in an environment without `Symbol.asyncDispose` (Node < 20.4, older browsers) after SWC downleveled the declaration to the TS helper.","commonSituations":"Shipping TS 5.2+ `await using` to Node 18 LTS or Safari versions without explicit resource management; assuming the compiled helper defines the missing symbol; CI on modern Node but production on older LTS.","solutions":["Polyfill before first use: `Symbol.asyncDispose ??= Symbol('Symbol.asyncDispose');` (and make resources expose the method under that same symbol).","Use a `DisposableStack`/`SuppressedError` polyfill package that installs both symbols.","Bump the runtime to Node >= 20.4 / a browser with Symbol.asyncDispose.","Replace `await using` with explicit `try/finally` + `await res[Symbol.asyncDispose]?.()` on old runtimes."],"exampleFix":"// before\n// entry.mjs — Node 18\nawait using lock = acquireLock(); // TypeError: Symbol.asyncDispose is not defined.\n\n// after\n// entry.mjs — polyfill first\nSymbol.asyncDispose ??= Symbol('Symbol.asyncDispose');\nawait using lock = acquireLock();","handlingStrategy":"fallback","validationCode":"// Feature-detect and polyfill before any `await using` executes (entry point).\nif (typeof Symbol.asyncDispose === 'undefined') {\n  Symbol.asyncDispose = Symbol('Symbol.asyncDispose');\n  // Resources must expose their method under this same symbol:\n  // obj[Symbol.asyncDispose] ??= () => obj.close();\n}\nif (typeof SuppressedError === 'undefined') {\n  globalThis.SuppressedError = class SuppressedError extends Error {};\n}","typeGuard":"const supportsAsyncDispose = (): boolean => typeof (Symbol as { asyncDispose?: symbol }).asyncDispose === 'symbol';","tryCatchPattern":"try {\n  await using res = open();\n} catch (err) {\n  if (err instanceof TypeError && /asyncDispose is not defined/.test(err.message)) {\n    // runtime lacks the symbol — manual async cleanup instead\n    const res = open();\n    try { /* work */ } finally { await res.close(); }\n  } else throw err;\n}","preventionTips":["Gate `await using` on a runtime version check (Node >= 20.4) or an entry-point polyfill.","Keep the polyfill in its own module imported first so the symbol exists before any resource module loads.","Add CI jobs on your oldest supported runtime to catch missing-symbol errors before deploy."],"tags":["await-using","explicit-resource-management","polyfill","symbol-asyncdispose"],"backgroundTag":"symbol-asyncdispose-undefined","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"}