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

  1. Check the file exists and is readable (fs.existsSync / fs.accessSync) before calling transform with a path.
  2. 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.
  3. Use absolute paths (path.resolve) so behavior does not depend on process.cwd.
  4. 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

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


AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17). Data as JSON: /api/errors/e1905feebe426c18. Report an issue: GitHub.