{"record":{"id":"c0b6ad59301d6f94","repo":"microsoft/semantic-kernel","slug":"directory-path-not-found-in-repository","errorCode":null,"errorMessage":"Directory {path} not found in repository.","messagePattern":"Directory (.+?) not found in repository\\.","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"python/samples/demos/document_generator/plugins/repo_file_plugin.py","lineNumber":51,"sourceCode":"        path = os.path.join(os.path.dirname(__file__), \"..\", \"..\", \"..\", \"..\")\n        for root, dirs, files in os.walk(path):\n            if file_name in files:\n                print(f\"Found file {file_name} in {root}.\")\n                with open(os.path.join(root, file_name)) as file:\n                    return file.read()\n        raise FileNotFoundError(f\"File {file_name} not found in repository.\")\n\n    @kernel_function(description=\"List all files or subdirectories in a directory.\")\n    def list_directory(\n        self, path: Annotated[str, \"Path of a directory relative to the root of the repository.\"]\n    ) -> Annotated[str, \"Returns a list of files and subdirectories as a string.\"]:\n        path = os.path.join(os.path.dirname(__file__), \"..\", \"..\", \"..\", \"..\", path)\n        try:\n            files = os.listdir(path)\n            # Join the list of files into a single string\n            return \"\\n\".join(files)\n        except FileNotFoundError:\n            raise FileNotFoundError(f\"Directory {path} not found in repository.\")\n","sourceCodeStart":33,"sourceCodeEnd":52,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/samples/demos/document_generator/plugins/repo_file_plugin.py#L33-L52","documentation":"Raised by RepoFilePlugin.list_directory when os.listdir(path) raises FileNotFoundError, i.e. the resolved directory does not exist. The directory path is computed relative to the repo root (four levels up).","triggerScenarios":"Calling list_directory with a relative path that does not correspond to an existing directory; pointing at a file instead of a directory (raises NotADirectoryError, not caught here); the base resolution is wrong.","commonSituations":"LLM guesses a directory path; the directory only exists on a different branch; case-sensitivity differences across platforms; the relative base hops are off after the plugin is moved.","solutions":["Confirm the directory exists relative to the actual repo root.","Verify the plugin's four-level '..' base still points to the repo root after any relocation.","Check the path with os.path.isdir before calling list_directory.","Provide the directory name via read_file_by_name-style search if unsure of the exact path."],"exampleFix":"// before\nplugin.list_directory('src')\n\n// after\nbase = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..'))\ntarget = os.path.join(base, 'python/samples')\nplugin.list_directory('python/samples')  # confirmed existing dir","handlingStrategy":"validation","validationCode":"import os\nbase = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..'))\ntarget = os.path.normpath(os.path.join(base, rel_path))\nif not os.path.isdir(target):\n    raise FileNotFoundError(f'Directory not at {target}')\nreturn os.listdir(target)","typeGuard":"import os\ndef is_repo_dir(rel_path: str) -> bool:\n    base = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..'))\n    target = os.path.normpath(os.path.join(base, rel_path))\n    return os.path.isdir(target)","tryCatchPattern":null,"preventionTips":["Check os.path.isdir before list_directory.","Confirm the four-level base resolves to the repo root after moves.","Document valid directory paths for the model."],"tags":["filesystem","kernel-plugin","directory-not-found","path-resolution"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}