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.

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.

Appendix: 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)