{"record":{"id":"aab0b69ff2b82f0b","repo":"microsoft/semantic-kernel","slug":"file-file-name-not-found-in-repository","errorCode":null,"errorMessage":"File {file_name} not found in repository.","messagePattern":"File (.+?) not found in repository\\.","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"python/samples/demos/document_generator/plugins/repo_file_plugin.py","lineNumber":39,"sourceCode":"        try:\n            with open(path) as file:\n                return file.read()\n        except FileNotFoundError:\n            raise FileNotFoundError(f\"File {path} not found in repository.\")\n\n    @kernel_function(\n        description=\"Read a file given the name of the file. Function will search for the file in the repository.\"\n    )\n    def read_file_by_name(\n        self, file_name: Annotated[str, \"The name of the file.\"]\n    ) -> Annotated[str, \"Returns the file content.\"]:\n        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":21,"sourceCodeEnd":52,"githubUrl":"https://github.com/microsoft/semantic-kernel/blob/c028a0c7dc4f0814cdcbaba9d998f187a41197bf/python/samples/demos/document_generator/plugins/repo_file_plugin.py#L21-L52","documentation":"Raised by RepoFilePlugin.read_file_by_name after os.walk over the repo root completes without finding a file matching file_name. Unlike read_file_by_path, this catches the not-found case at the end of the walk rather than via an exception.","triggerScenarios":"Calling read_file_by_name with a filename that does not exist anywhere under the resolved repo root; filename typo; the file is in a directory excluded from the walk or in .gitignore'd paths that still exist (gitignored files are still walked by os.walk).","commonSituations":"LLM supplies a plausible but wrong filename; duplicate filenames across the repo where the first match is returned but the caller expected another; very large repos where os.walk is slow.","solutions":["Confirm the exact filename (including extension and case) exists in the repository.","Pre-search the tree yourself (glob) to confirm uniqueness/existence before calling.","If multiple files share the name, use read_file_by_path with the specific relative path instead.","Ensure the resolved base (four levels up) is the actual repository root."],"exampleFix":"// before\nplugin.read_file_by_name('config')  # missing extension\n\n// after\nplugin.read_file_by_name('config.py')","handlingStrategy":"validation","validationCode":"import os\nbase = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..'))\nmatches = []\nfor root, _, files in os.walk(base):\n    if file_name in files:\n        matches.append(os.path.join(root, file_name))\nif not matches:\n    raise FileNotFoundError(f'{file_name} not found under {base}')\nif len(matches) > 1:\n    raise ValueError(f'{file_name} is ambiguous: {matches}')","typeGuard":"import os\ndef file_name_exists(file_name: str) -> bool:\n    base = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..'))\n    for _, _, files in os.walk(base):\n        if file_name in files:\n            return True\n    return False","tryCatchPattern":null,"preventionTips":["Confirm exact filename + extension before calling.","Detect duplicate names to avoid ambiguous first-match behavior.","Use the path-based reader for specificity."],"tags":["filesystem","kernel-plugin","file-not-found","search"],"backgroundTag":null,"analyzedSha":"c028a0c7dc4f0814cdcbaba9d998f187a41197bf","analyzedAt":"2026-08-13T13:48:05.040Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}