shadcn-ui/ui · error

Unsupported path type: ${options.path}

Error message

Unsupported path type: ${options.path}

What it means

Thrown by migrateRtl when fs.stat succeeds but the entry is neither a regular file nor a directory — sockets, FIFOs, devices, or broken symlinks. The RTL migrator only handles files (transform in place) and directories (recursive glob), so other inode types are rejected up front.

Source

Thrown at packages/shadcn/src/migrations/migrate-rtl.ts:58

    } else {
      const fullPath = path.resolve(basePath, options.path)
      const stat = await fs.stat(fullPath).catch(() => null)

      if (!stat) {
        throw new Error(`File not found: ${options.path}`)
      }

      if (stat.isDirectory()) {
        basePath = fullPath
        files = await fg("**/*.{js,ts,jsx,tsx}", {
          cwd: basePath,
          onlyFiles: true,
          ignore: ["**/node_modules/**"],
        })
      } else if (stat.isFile()) {
        files = [options.path]
      } else {
        throw new Error(`Unsupported path type: ${options.path}`)
      }
    }

    if (files.length === 0) {
      throw new Error(`No files found matching: ${options.path}`)
    }
  } else {
    // Default: use ui path from components.json.
    if (!config.resolvedPaths.ui) {
      throw new Error(
        "Could not find a valid `ui` path in your `components.json`. Please provide a path or glob pattern."
      )
    }

    basePath = config.resolvedPaths.ui
    files = await fg("**/*.{js,ts,jsx,tsx}", {
      cwd: basePath,
      onlyFiles: true,

View on GitHub (pinned to efac598707)

Solutions

  1. Point --path at a real source file or directory.
  2. Inspect symlinks with `readlink <path>` and fix or remove broken ones.
  3. Use a glob pattern so fast-glob filters to real files.

Example fix

// before
shadcn migrate rtl --path /tmp/app.sock

// after
shadcn migrate rtl --path ./src/components/ui
Defensive patterns

Strategy: type-guard

Validate before calling

import fs from 'fs/promises'
import path from 'path'

async function assertPlainFileOrDir(rel: string, cwd: string) {
  const stat = await fs.stat(path.resolve(cwd, rel)).catch(() => null)
  if (stat && !stat.isFile() && !stat.isDirectory()) {
    throw new Error(`Unsupported path type: ${rel}`)
  }
}

Type guard

import { Stats } from 'fs'

function isMigratableStat(stat: Stats | null): boolean {
  return Boolean(stat && (stat.isFile() || stat.isDirectory()))
}

Prevention

When it happens

Trigger: Pointing --path at a special file (e.g. /dev/null, a socket); a dangling symlink; a shell glob that expanded to a non-file path.

Common situations: Accidental special-file path; broken symlink left from a failed package install.

Related errors


AI-assisted analysis of shadcn-ui/ui@efac598707 (2026-08-12). Data as JSON: /api/errors/cf1420aa5f21a5be. Report an issue: GitHub.