Skip to content

scan crashes with EISDIR when .clinerules is a directory (e.g. inside cached plugin dirs) #147

Description

`agentshield scan` crashes with an uncaught `EISDIR` when a config root contains `.clinerules` as a directory rather than a file (Cline supports both conventions).

Repro: run `agentshield scan -p ~/.claude` in an environment where a cached Claude Code plugin (e.g. ponytail) ships `.clinerules/` as a directory of rule files.

Stack:

Error: EISDIR: illegal operation on a directory, read
    at readFileSync (node:fs:484:20)
    at addDiscoveredFile (dist/index.js:442:19)
    at scanClaudeRoot (dist/index.js:229:7)
    at discoverConfigFiles (dist/index.js:97:5)

Root cause: in `scanClaudeRoot`'s `directFiles` list, `.clinerules` is registered as a plain file and discovered via `existsSync(fullPath)` only, then passed straight to `addDiscoveredFile`, which calls `readFileSync` unconditionally. `.clinerules` is also registered in the `subdirs` list (correctly guarded with `statOrNull(dirPath)?.isDirectory()`), so the codebase already assumes it can be either — but the `directFiles` branch doesn't guard against the directory case.

Suggested fix: guard the `directFiles` loop with `statOrNull(fullPath)?.isFile()` instead of `existsSync(fullPath)`, matching the pattern already used elsewhere in the file (e.g. in `subdirs` and `discoverReferencedHookScripts`).

Env: Node v24.19.0, Windows 11, ecc-agentshield 2.2.1

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions