{"record":{"id":"37c03b044e3742a2","repo":"symfony/finder","slug":"e-getmessage-dynamic-wrapped-unexpectedvalueexception","errorCode":null,"errorMessage":"$e->getMessage() (dynamic; wrapped \\UnexpectedValueException message, rethrown as AccessDeniedException)","messagePattern":"\\$e->getMessage\\(\\) \\(dynamic; wrapped \\\\UnexpectedValueException message, rethrown as AccessDeniedException\\)","errorType":"exception","errorClass":"Symfony\\Component\\Finder\\Exception\\AccessDeniedException","httpStatus":null,"severity":"error","filePath":"Iterator/RecursiveDirectoryIterator.php","lineNumber":111,"sourceCode":"    /**\n     * @throws AccessDeniedException\n     */\n    public function getChildren(): \\RecursiveDirectoryIterator\n    {\n        try {\n            $children = parent::getChildren();\n\n            if ($children instanceof self) {\n                // parent method will call the constructor with default arguments, so unreadable dirs won't be ignored anymore\n                $children->ignoreUnreadableDirs = $this->ignoreUnreadableDirs;\n\n                // performance optimization to avoid redoing the same work in all children\n                $children->rootPath = $this->rootPath;\n            }\n\n            return $children;\n        } catch (\\UnexpectedValueException $e) {\n            throw new AccessDeniedException($e->getMessage(), $e->getCode(), $e);\n        }\n    }\n\n    public function next(): void\n    {\n        $this->ignoreFirstRewind = false;\n\n        parent::next();\n    }\n\n    public function rewind(): void\n    {\n        // some streams like FTP are not rewindable, ignore the first rewind after creation,\n        // as newly created DirectoryIterator does not need to be rewound\n        if ($this->ignoreFirstRewind) {\n            $this->ignoreFirstRewind = false;\n\n            return;","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/symfony/finder/blob/4d6c057bfd67c5a93e8025c85ca9364cba7e260a/Iterator/RecursiveDirectoryIterator.php#L93-L129","documentation":"RecursiveDirectoryIterator::getChildren() wraps any \\UnexpectedValueException thrown by the underlying SplFilesystemIterator (typically when a subdirectory cannot be opened or read) into Symfony's AccessDeniedException, preserving message, code, and previous exception. The library throws it so consumers can distinguish permission/unreadable-directory failures during filesystem traversal.","triggerScenarios":"Calling getChildren() on a directory entry whose underlying open fails: unreadable directory permissions, a directory removed between iteration steps, or an entry that disappears during iteration (race with concurrent deletion).","commonSituations":"Scanning vendor or cache directories with restrictive permissions, iterating directories changed by other processes (build cleanup, tmp reaping), running as a user without read access to nested directories, containers with read-only mounts.","solutions":["Catch AccessDeniedException (or use the ignoreUnreadableDirs constructor flag / Finder's ignoreUnreadableDirs()) so iteration skips unreadable directories","Fix filesystem permissions (chmod/chown) so the iterating user can read the affected directory","Check that the directory still exists before descending; re-stat or refresh the iterator","Inspect the wrapped previous exception to confirm it is an UnexpectedValueException from SplFilesystemIterator open failure"],"exampleFix":"// before\nforeach ($iterator as $file) {\n    $children = $iterator->getChildren(); // throws AccessDeniedException\n}\n// after\n$iterator = new \\Symfony\\Component\\Finder\\Iterator\\RecursiveDirectoryIterator($path, $flags, true); // ignoreUnreadableDirs\n// or\ntry {\n    $children = $iterator->getChildren();\n} catch (AccessDeniedException $e) {\n    // skip unreadable directory\n}","handlingStrategy":"try-catch","validationCode":"if (!is_dir($dir) || !is_readable($dir)) { /* skip or fix perms */ }","typeGuard":"function isReadableDir(string $path): bool { return is_dir($path) && is_readable($path); }","tryCatchPattern":"try { $children = $iterator->getChildren(); } catch (\\Symfony\\Component\\Finder\\Exception\\AccessDeniedException $e) { // skip unreadable dir }","preventionTips":["Enable ignoreUnreadableDirs (or Finder::ignoreUnreadableDirs()) for resilient traversal","Run the process as a user with read access to all scanned trees","Avoid scanning directories that other processes delete/rename concurrently","Check is_readable() on directories before descending"],"tags":["filesystem","permissions","iteration"],"backgroundTag":"permission-denied","analyzedSha":"4d6c057bfd67c5a93e8025c85ca9364cba7e260a","analyzedAt":"2026-09-13T07:49:33.433Z","contentChangedAt":"2026-09-13T07:49:33.433Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}