denoland/deno · error · ERR_FS_INVALID_SYMLINK_TYPE

ERR_FS_INVALID_SYMLINK_TYPE

ERR_FS_INVALID_SYMLINK_TYPE

Error message

Symlink type must be one of "dir", "file", or "junction". Received "${type}"

What it means

The optional third argument of fs.symlink() carries a Windows-specific type hint that may only be 'dir', 'file' or 'junction'; stringToSymlinkType maps those to UV_FS_SYMLINK_* flags and throws ERR_FS_INVALID_SYMLINK_TYPE for anything else. On POSIX the argument is ignored, so an invalid value only ever comes from the caller's own input.

Source

Thrown at ext/node/polyfills/internal/fs/utils.mjs:830

  }

  throw new ERR_INVALID_ARG_VALUE("flags", flags);
}

export const stringToSymlinkType = hideStackFrames((type) => {
  let flags = 0;
  if (typeof type === "string") {
    switch (type) {
      case "dir":
        flags |= UV_FS_SYMLINK_DIR;
        break;
      case "junction":
        flags |= UV_FS_SYMLINK_JUNCTION;
        break;
      case "file":
        break;
      default:
        throw new ERR_FS_INVALID_SYMLINK_TYPE(type);
    }
  }
  return flags;
});

// converts Date or number to a fractional UNIX timestamp
export function toUnixTimestamp(time, name = "time") {
  // eslint-disable-next-line eqeqeq
  if (typeof time === "string" && +time == time) {
    return +time;
  }
  if (NumberIsFinite(time)) {
    if (time < 0) {
      return DateNow() / 1000;
    }
    return time;
  }
  if (isDate(time)) {

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Omit the type on POSIX, or pass one of 'dir' | 'file' | 'junction'.
  2. On Windows pass 'dir' when the target is a directory so the reparse point is created correctly.
  3. Whitelist config-driven values before use.

Example fix

// before
fs.symlinkSync('/opt/app/v1', '/opt/app/current', 'mylink'); // throws

// after
fs.symlinkSync('/opt/app/v1', '/opt/app/current');            // POSIX: type optional
// Windows, target is a directory:
fs.symlinkSync('D:\\data', 'C:\\link', 'dir');
Defensive patterns

Strategy: validation

Validate before calling

const SYMLINK_TYPES = new Set(['dir', 'file', 'junction']);
if (type !== undefined && !SYMLINK_TYPES.has(type)) {
  throw new TypeError(`symlink type must be dir|file|junction, got ${JSON.stringify(type)}`);
}

Type guard

function isSymlinkType(v) {
  return v === undefined || v === 'dir' || v === 'file' || v === 'junction';
}

Prevention

When it happens

Trigger: fs.symlink(target, path, 'symbolic') or 'soft'; passing the link's display name as the third argument — the parameter is a type hint, not a name; symlink-type strings generated from templates or config.

Common situations: Misreading the signature as symlink(target, path, linkName); copy-pasting 'soft' from other tools' documentation; CLI wrappers that forward a user string unchecked.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/21f3cf9af3b28f89. Report an issue: GitHub.