Skip to content

fix: handle symlinks in dev mode linking#390

Merged
technophile-04 merged 1 commit intomainfrom
fix-symlink-dev
Feb 9, 2026
Merged

fix: handle symlinks in dev mode linking#390
technophile-04 merged 1 commit intomainfrom
fix-symlink-dev

Conversation

@technophile-04
Copy link
Collaborator

Description:

After #386, if you try to run the extension in dev mode it was failing with the below error:

Error
❯ yarn cli ../402-updates-extension -e create-eth-extensions --dev

 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 | Create Scaffold-ETH 2 app |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+



✔ 📁 Create project directory /Users/shivbhonde/Desktop/github/402-updates-extension
✖ EPERM: operation not permitted, link
  '/Users/shivbhonde/Desktop/github/create-eth/templates/base/.claude/skills/defi-protocol-templates' ->
  '/Users/shivbhonde/Desktop/github/402-updates-extension/.claude/skills/defi-protocol-templates'
◼ 📦 Installing dependencies with yarn, this could take a while
◼ 🪄 Formatting files
◼ 📡 Initializing Git repository
ERROR Error occurred Error: EPERM: operation not permitted, link '/Users/shivbhonde/Desktop/github/create-eth/templates/base/.claude/skills/defi-protocol-templates' -> '/Users/shivbhonde/Desktop/github/402-updates-extension/.claude/skills/defi-protocol-templates'
    at async link (node:internal/fs/promises:1052:10)
    at async file:///Users/shivbhonde/Desktop/github/create-eth/dist/cli.js:81:13
    at async Promise.all (index 0)
    at async linkRecursive (file:///Users/shivbhonde/Desktop/github/create-eth/dist/cli.js:70:9)
    at async file:///Users/shivbhonde/Desktop/github/create-eth/dist/cli.js:81:13
    at async Promise.all (index 1)
    at async linkRecursive (file:///Users/shivbhonde/Desktop/github/create-eth/dist/cli.js:70:9)
    at async file:///Users/shivbhonde/Desktop/github/create-eth/dist/cli.js:81:13
    at async Promise.all (index 2)
    at async linkRecursive (file:///Users/shivbhonde/Desktop/github/create-eth/dist/cli.js:70:9) {
  errno: -1,
  code: 'EPERM',
  syscall: 'link',
  path: '/Users/shivbhonde/Desktop/github/create-eth/templates/base/.claude/skills/defi-protocol-templates',
  dest: '/Users/shivbhonde/Desktop/github/402-updates-extension/.claude/skills/defi-protocol-templates'
}
Uh oh! 😕 Sorry about that! Exiting...

create-eth on  main [$] is 📦 v2.0.6 via  v22.11.0

Why this happend?

  1. Templates contain symlinks - The .claude/skills/ directory has symlinks pointing to ../../.agents/skills/:
    defi-protocol-templates -> ../../.agents/skills/defi-protocol-templates
    solidity-security -> ../../.agents/skills/solidity-security

  2. lstatSync doesn't follow symlinks - The original code used
    lstatSync(source).isDirectory() to check if a path is a directory. Unlike statSync,
    lstatSync returns info about the symlink itself, not its target. So a symlink pointing to a
    directory returns false for isDirectory().

  3. Hard links don't work for symlinks to directories - When the symlink wasn't detected as a
    directory, the code fell through to link(source, destination) which creates a hard link. On
    macOS (and most Unix systems), you cannot create hard links for symlinks that point to
    directories - this fails with EPERM.

The Fix

Check if the source is a symlink first using stat.isSymbolicLink(), and if so, read the link target with readlinkSync and recreate the symlink at the destination using symlink()

The linkRecursive function now properly handles symbolic links by
recreating them at the destination instead of attempting to hard link
them, which caused EPERM errors on macOS.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Member

@rin-st rin-st left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking and working great!

@technophile-04 technophile-04 merged commit de3a4e5 into main Feb 9, 2026
7 checks passed
@technophile-04 technophile-04 deleted the fix-symlink-dev branch February 9, 2026 13:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants