shadcn-ui/ui · error

Unsupported path type: ${options.path}

Error message

Unsupported path type: ${options.path}

What it means

Thrown by migrateRadix when fs.stat succeeds but the entry is neither a regular file nor a directory — i.e. a socket, FIFO, character/block device, or broken symlink. The migrator only knows how to handle files (migrate in place) and directories (recursively glob for code files), so any other inode type is rejected.

Source

Thrown at packages/shadcn/src/migrations/migrate-radix.ts:138

    } 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(
        "We could not find a valid `ui` path in your `components.json` file. Please ensure you have a valid `ui` path in your `components.json` file."
      )
    }

    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 file or directory containing source code.
  2. If a symlink, fix or remove it (`readlink <path>` to inspect).
  3. Use a glob pattern instead, which fast-glob will resolve to actual files only.

Example fix

// before
shadcn migrate radix --path /tmp/my-fifo

// after — target a source file or directory
shadcn migrate radix --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}`)
  }
  return stat
}

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 /dev/null, a unix socket, a named pipe, or a dangling symlink; on some systems, pointing at a symlink whose target has been removed returns a stat for the link itself which is neither isFile nor isDirectory in edge cases.

Common situations: Accidental glob expansion in the shell produced a special file path; path is a broken symlink left by a failed install.

Related errors


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