{"record":{"id":"c81b043d6d7b9fe3","repo":"apache/cassandra","slug":"can-t-open-r-for-reading-no-matching-file-found","errorCode":null,"errorMessage":"Can't open %r for reading: no matching file found","messagePattern":"Can't open %r for reading: no matching file found","errorType":"exception","errorClass":"IOError","httpStatus":null,"severity":"error","filePath":"pylib/cqlshlib/copyutil.py","lineNumber":906,"sourceCode":"        \"\"\"\n         Return a source generator. Each source is a named tuple\n         wrapping the source input, file name and a boolean indicating\n         if it requires closing.\n        \"\"\"\n        def make_source(fname):\n            try:\n                return open(fname, 'r')\n            except IOError as e:\n                raise IOError(\"Can't open %r for reading: %s\" % (fname, e))\n\n        for path in paths.split(','):\n            path = path.strip()\n            if os.path.isfile(path):\n                yield make_source(path)\n            else:\n                result = glob.glob(path)\n                if len(result) == 0:\n                    raise IOError(\"Can't open %r for reading: no matching file found\" % (path,))\n\n                for f in result:\n                    yield make_source(f)\n\n    def start(self):\n        self.sources = self.get_source(self.fname)\n        self.next_source()\n\n    @property\n    def exhausted(self):\n        return not self.current_source\n\n    def next_source(self):\n        \"\"\"\n         Close the current source, if any, and open the next one. Return true\n         if there is another source, false otherwise.\n        \"\"\"\n        self.close_current_source()","sourceCodeStart":888,"sourceCodeEnd":924,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/pylib/cqlshlib/copyutil.py#L888-L924","documentation":"Before opening files for COPY FROM, each comma-separated path is checked: if it is not a literal file, it is treated as a glob pattern; if the glob returns no matches, an IOError is raised saying no matching file was found.","triggerScenarios":"COPY FROM '/path/data*.csv' (or a plain path) where os.path.isfile(path) is false and glob.glob(path) returns an empty list — the file does not exist or the glob pattern matches nothing in the working directory.","commonSituations":"Typo in the filename, running cqlsh from a different working directory than expected, glob pattern with wrong extension (*.CSV vs *.csv on case-sensitive filesystems), files not yet produced by an upstream export job.","solutions":["Verify the path/pattern with ls or glob before running COPY FROM","Use an absolute path or cd to the directory containing the file first","Check case sensitivity of the extension on Linux filesystems"],"exampleFix":"// before\nCOPY t FROM './exports/data*.csv';  # no match\n// after\n$ ls ./exports/\ndata-2026-09-01.csv\nCOPY t FROM './exports/data-2026-09-01.csv';","handlingStrategy":"validation","validationCode":"import glob, os\np = '/path/data*.csv'\nif not os.path.isfile(p) and not glob.glob(p):\n    raise SystemExit(f\"No file matches {p}\")","typeGuard":null,"tryCatchPattern":"try:\n    run_copy_from(fname)\nexcept IOError:\n    print(\"No matching input file; check path/pattern and cwd\")","preventionTips":["ls the glob pattern before COPY FROM","Use absolute paths","Mind case-sensitive extensions on Linux"],"tags":["cqlsh","copy","file-not-found","glob"],"backgroundTag":"file-not-found","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}