{"record":{"id":"3adc45e88cbb237e","repo":"yamadashy/repomix","slug":"permission-denied-while-scanning-directory-please","errorCode":null,"errorMessage":"Permission denied while scanning directory. Please check folder access permissions for your terminal app. path: ${rootDir}","messagePattern":"Permission denied while scanning directory\\. Please check folder access permissions for your terminal app\\. path: (.+?)","errorType":"exception","errorClass":"PermissionError","httpStatus":null,"severity":"error","filePath":"src/core/file/fileSearch.ts","lineNumber":230,"sourceCode":"\n        logger.debug(`[stdin mode] Total include patterns after merge: ${includePatterns.length}`);\n      }\n    }\n\n    // If no include patterns at all, default to all files\n    if (includePatterns.length === 0) {\n      includePatterns = ['**/*'];\n    }\n\n    logger.trace('Include patterns with explicit files:', includePatterns);\n    logger.trace('Ignore patterns:', adjustedIgnorePatterns);\n    logger.trace('Ignore file patterns (for globby):', ignoreFilePatterns);\n\n    const handleGlobbyError = (error: unknown): never => {\n      // Handle EPERM errors specifically\n      const code = (error as NodeJS.ErrnoException | { code?: string })?.code;\n      if (code === 'EPERM' || code === 'EACCES') {\n        throw new PermissionError(\n          `Permission denied while scanning directory. Please check folder access permissions for your terminal app. path: ${rootDir}`,\n          rootDir,\n        );\n      }\n      throw error;\n    };\n\n    logger.debug('[globby] Starting file search...');\n    const globbyStartTime = Date.now();\n\n    let filePaths: string[];\n    let emptyDirPaths: string[] = [];\n\n    if (config.output.includeEmptyDirectories) {\n      // Single traversal returning both files and directories. The previous implementation\n      // ran globby twice with identical options (once for files, once for directories),\n      // which re-walks the tree and re-parses every .gitignore/.repomixignore, roughly\n      // doubling the discovery cost. Using `objectMode: true` lets us partition the entries","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/yamadashy/repomix/blob/f465ad909315a22120636baf03fa5e28701a50cb/src/core/file/fileSearch.ts#L212-L248","documentation":"Repomix wraps EPERM/EACCES errors raised while globby scans directories into a PermissionError. It signals that the process lacks OS-level read permission on the directory being packed. The path reported is the root directory of the scan, not necessarily the specific unreadable subdirectory.","triggerScenarios":"Calling searchFiles (via pack/repomix run) when globby's directory walk hits a folder the current user cannot read, causing globby to emit an error with code 'EPERM' or 'EACCES', which handleGlobbyError converts to PermissionError.","commonSituations":"Scanning directories protected by macOS TCC (Desktop/Documents/Downloads not granted to the terminal app), reading root-owned or other-user directories on Linux, or corporate-restricted folders.","solutions":["Grant the terminal app Full Disk Access (macOS: System Settings > Privacy & Security > Full Disk Access) or access to the specific folder (Files and Folders).","Run repomix from a directory you own, or chmod/chown the target directory so the current user can read it.","Exclude the unreadable directory via repomix ignore configuration so globby never descends into it.","On Linux, run under a user with read access (e.g. sudo) only if appropriate for your environment."],"exampleFix":"// before: scanning a protected folder\nrepomix ~/Library/Mobile\\ Documents\n\n// after: pick an accessible copy or grant access first\nsudo chown -R \"$USER\" ~/protected-project\n# or add to repomix ignore: \"protected-folder/\"","handlingStrategy":"try-catch","validationCode":"import { accessSync, constants } from 'node:fs';\ntry {\n  accessSync(rootDir, constants.R_OK | constants.X_OK);\n} catch {\n  throw new Error(`No read permission on ${rootDir} — fix permissions or exclude this folder before packing.`);\n}","typeGuard":"const isErrnoException = (e: unknown): e is NodeJS.ErrnoException =>\n  typeof e === 'object' && e !== null && 'code' in e && typeof (e as { code: unknown }).code === 'string';","tryCatchPattern":"try {\n  await repomix.pack(...);\n} catch (e) {\n  if (e instanceof PermissionError || (isErrnoException(e) && ['EPERM', 'EACCES'].includes(e.code))) {\n    console.error(`Cannot read ${rootDir}: grant the terminal Full Disk Access or exclude this folder.`);\n  } else throw e;\n}","preventionTips":["Grant your terminal app Full Disk Access / Files-and-Folders permissions before scanning user-protected directories (macOS).","Check readability with `ls -la` or fs.accessSync(rootDir, R_OK) before packing.","Add known-protected directories to the ignore configuration.","Run repomix as a user that owns or can read the target tree."],"tags":["filesystem","permissions","globby"],"backgroundTag":"eacces-permission-denied","analyzedSha":"f465ad909315a22120636baf03fa5e28701a50cb","analyzedAt":"2026-08-29T01:27:42.024Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}