swc-project/swc · error · ReferenceError
Decorators can't be placed on different accessors with for t
Error message
Decorators can't be placed on different accessors with for the same property (${element.key}). What it means
When the napi `transform` function receives a plain string it treats it as a filename and loads the file from disk with c.cm.load_file(...).expect("failed to load file"). Any I/O failure (missing file, unreadable, wrong path) panics in Rust, which napi-rs converts into a JS exception carrying this message. The panic occurs inside try_with, but because expect aborts rather than emitting to the handler, the JS side gets the raw panic instead of a structured diagnostic.
Source
Thrown at crates/swc_ecma_transforms_base/src/helpers/generated/_decorate.rs:62
var newElements = [];
var isSameElement = function isSameElement(other) {
return other.kind === "method" && other.key === element.key && other.placement === element.placement;
};
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
var other;
if (element.kind === "method" && (other = newElements.find(isSameElement))) {
if (_isDataDescriptor(element.descriptor) || _isDataDescriptor(other.descriptor)) {
if (_hasDecorators(element) || _hasDecorators(other)) {
throw new ReferenceError("Duplicated methods (" + element.key + ") can't be decorated.");
}
other.descriptor = element.descriptor;
} else {
if (_hasDecorators(element)) {
if (_hasDecorators(other)) {
throw new ReferenceError("Decorators can't be placed on different accessors with for " + "the same property (" + element.key + ").");
}
other.decorators = element.decorators;
}
_coalesceGetterSetter(element, other);
}
} else {
newElements.push(element);
}
}
return newElements;
}
function _hasDecorators(element) {
return element.decorators && element.decorators.length;
}
function _isDataDescriptor(desc) {
return desc !== undefined && !(desc.value === undefined && desc.writable === undefined);
}View on GitHub (pinned to 5176682b65)
Solutions
- Check the file exists and is readable (fs.existsSync / fs.accessSync) before calling transform with a path.
- If you meant to transform source you already hold, pass the program-object form of the first argument instead of a bare string, or use a parse-then-transform flow.
- Use absolute paths (path.resolve) so behavior does not depend on process.cwd.
- Wrap the call in try/catch; the JS exception message includes 'failed to load file' with the underlying io error context.
Example fix
// before: bare string path that may not exist
const out = transform('src/app.ts', opts, false);
// after: resolve and check first
const file = path.resolve('src/app.ts');
if (!fs.existsSync(file)) throw new Error(`missing input: ${file}`);
const out = transform(file, opts, false); Defensive patterns
Strategy: validation
Validate before calling
import fs from 'node:fs';
import path from 'node:path';
function transformFileSafe(input, opts) {
if (typeof input === 'string') {
const file = path.resolve(input);
if (!fs.existsSync(file)) {
throw new Error(`transform target does not exist: ${file}`);
}
fs.accessSync(file, fs.constants.R_OK);
return transform(file, opts, false);
}
return transform(input, opts, false); // program-object form
} Type guard
function isTransformFilename(v: unknown): v is string {
// The binding treats ANY plain string as a filename.
return typeof v === 'string';
} Try / catch
try {
out = transform(input, opts, false);
} catch (e) {
if (/failed to load file/.test(String(e?.message))) {
throw new Error(`swc could not load the input file: ${input}`, { cause: e });
}
throw e;
} Prevention
- Remember the string overload means 'path', not 'code' - pass program objects for in-memory transforms.
- Prefer absolute paths and verify existence before calling.
- Catch the JS-side panic and rethrow with the offending path for actionable logs.
When it happens
Trigger: Calling transform('some/file.js', opts, false) from @swc/core-style code where the first argument is a path string and that path does not exist or is not readable; passing a filename when you meant to pass program JSON (the object form takes a different branch); relative paths resolved against an unexpected process cwd.
Common situations: Calling the low-level binding with the same arguments as the high-level @swc/core transform (which accepts either code or path but validates first); monorepo tools resolving paths relative to the package root while the process cwd is the workspace root; deleted or renamed files still referenced by a manifest.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- Duplicated methods (${element.key}) can't be decorated.
- Invalid attempt to iterate non-iterable instance. In order t
- Duplicated element (${element.key})
- Duplicated element (${elements[j].key})
- unknown key: {k}
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/e1905feebe426c18.
Report an issue: GitHub.