{"record":{"id":"21f3cf9af3b28f89","repo":"denoland/deno","slug":"err-fs-invalid-symlink-type","errorCode":"ERR_FS_INVALID_SYMLINK_TYPE","errorMessage":"Symlink type must be one of \"dir\", \"file\", or \"junction\". Received \"${type}\"","messagePattern":"Symlink type must be one of \"dir\", \"file\", or \"junction\"\\. Received \"(.+?)\"","errorType":"validation","errorClass":"ERR_FS_INVALID_SYMLINK_TYPE","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/fs/utils.mjs","lineNumber":830,"sourceCode":"  }\n\n  throw new ERR_INVALID_ARG_VALUE(\"flags\", flags);\n}\n\nexport const stringToSymlinkType = hideStackFrames((type) => {\n  let flags = 0;\n  if (typeof type === \"string\") {\n    switch (type) {\n      case \"dir\":\n        flags |= UV_FS_SYMLINK_DIR;\n        break;\n      case \"junction\":\n        flags |= UV_FS_SYMLINK_JUNCTION;\n        break;\n      case \"file\":\n        break;\n      default:\n        throw new ERR_FS_INVALID_SYMLINK_TYPE(type);\n    }\n  }\n  return flags;\n});\n\n// converts Date or number to a fractional UNIX timestamp\nexport function toUnixTimestamp(time, name = \"time\") {\n  // eslint-disable-next-line eqeqeq\n  if (typeof time === \"string\" && +time == time) {\n    return +time;\n  }\n  if (NumberIsFinite(time)) {\n    if (time < 0) {\n      return DateNow() / 1000;\n    }\n    return time;\n  }\n  if (isDate(time)) {","sourceCodeStart":812,"sourceCodeEnd":848,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/fs/utils.mjs#L812-L848","documentation":"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.","triggerScenarios":"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.","commonSituations":"Misreading the signature as symlink(target, path, linkName); copy-pasting 'soft' from other tools' documentation; CLI wrappers that forward a user string unchecked.","solutions":["Omit the type on POSIX, or pass one of 'dir' | 'file' | 'junction'.","On Windows pass 'dir' when the target is a directory so the reparse point is created correctly.","Whitelist config-driven values before use."],"exampleFix":"// before\nfs.symlinkSync('/opt/app/v1', '/opt/app/current', 'mylink'); // throws\n\n// after\nfs.symlinkSync('/opt/app/v1', '/opt/app/current');            // POSIX: type optional\n// Windows, target is a directory:\nfs.symlinkSync('D:\\\\data', 'C:\\\\link', 'dir');","handlingStrategy":"validation","validationCode":"const SYMLINK_TYPES = new Set(['dir', 'file', 'junction']);\nif (type !== undefined && !SYMLINK_TYPES.has(type)) {\n  throw new TypeError(`symlink type must be dir|file|junction, got ${JSON.stringify(type)}`);\n}","typeGuard":"function isSymlinkType(v) {\n  return v === undefined || v === 'dir' || v === 'file' || v === 'junction';\n}","tryCatchPattern":null,"preventionTips":["The third argument of fs.symlink is a type hint, never a link name.","Only Windows interprets it — omit it elsewhere.","Whitelist config-driven values before they reach the call."],"tags":["filesystem","symlink","windows","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}