swc-project/swc · error · ReferenceError
Duplicated methods (${element.key}) can't be decorated.
Error message
Duplicated methods (${element.key}) can't be decorated. What it means
The napi `parseFileSync(path, opts)` function loads the JS/TS file from disk via SourceMap::load_file and unwraps it with .expect("failed to read program file"). Any I/O failure - missing path, permission denied, or content the loader cannot handle - becomes a Rust panic that napi-rs reports to JS as an exception with this message. Unlike parse errors, nothing is captured by the swc handler because the panic happens before parsing starts.
Source
Thrown at crates/swc_ecma_transforms_base/src/helpers/generated/_decorate.rs:56
}
function _coalesceGetterSetter(element, other) {
if (element.descriptor.get !== undefined) other.descriptor.get = element.descriptor.get;
else other.descriptor.set = element.descriptor.set;
}
function _coalesceClassElements(elements) {
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;
}View on GitHub (pinned to 5176682b65)
Solutions
- Verify the path before calling: use fs.existsSync / fs.statSync and resolve it to an absolute path with path.resolve.
- Check file readability (fs.accessSync(p, fs.constants.R_OK)) and fix permissions if needed.
- Prefer the buffer-based parse API (parseSync with source text) when you already have the contents in memory, avoiding filesystem coupling entirely.
- Wrap the call in try/catch and surface the JS exception message - it contains the path context from the panic.
Example fix
// before: panics inside Rust when the file is missing
const out = parseFileSync('src/app.ts', opts);
// after: validate first, then call
const file = path.resolve('src/app.ts');
fs.accessSync(file, fs.constants.R_OK);
const out = parseFileSync(file, opts); Defensive patterns
Strategy: validation
Validate before calling
import fs from 'node:fs';
import path from 'node:path';
function parseFileSyncSafe(relPath, opts) {
const file = path.resolve(relPath); // cwd-independent
const st = fs.statSync(file); // throws ENOENT/EACCES with a clear JS error
if (!st.isFile()) throw new Error(`not a file: ${file}`);
fs.accessSync(file, fs.constants.R_OK);
return parseFileSync(file, opts);
} Type guard
function isReadableFile(p: string): boolean {
try {
return fs.statSync(p).isFile();
} catch {
return false;
}
} Try / catch
try {
result = parseFileSync(file, opts);
} catch (e) {
if (/failed to read program file/.test(String(e?.message))) {
throw new Error(`swc could not read ${file}: check the path and permissions`, { cause: e });
}
throw e;
} Prevention
- Resolve every path against an explicit base directory; never rely on process.cwd in tools.
- When the source is already in memory, use the source-text parse API instead of the file variant.
- In watch/build pipelines, handle delete events by removing files from the worklist before parsing.
When it happens
Trigger: Calling parseFileSync('src/foo.ts', opts) where the file does not exist, is a directory, has no read permission, or the path is relative to a different working directory than assumed (the Rust side resolves it from the process cwd).
Common situations: Bundlers or CLIs run from a different cwd so a relative path resolves wrong; globs that include deleted files; permission-restricted mount or Docker volume without read access; case-sensitive filesystem mismatches after cloning a repo from Windows.
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
- Decorators can't be placed on different accessors with for t
- 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/ac14707147b447d5.
Report an issue: GitHub.