{"record":{"id":"e4bf01bc4f18ee3e","repo":"apache/cassandra","slug":"cannot-suffix-an-empty-path","errorCode":null,"errorMessage":"Cannot suffix an empty path","messagePattern":"Cannot suffix an empty path","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/io/util/File.java","lineNumber":786,"sourceCode":"    public FileWriter newWriter(WriteMode mode) throws IOException\n    {\n        return new FileWriter(this, mode);\n    }\n\n    public FileOutputStreamPlus newOutputStream(WriteMode mode) throws NoSuchFileException\n    {\n        return new FileOutputStreamPlus(this, mode);\n    }\n\n    public FileInputStreamPlus newInputStream() throws NoSuchFileException\n    {\n        return new FileInputStreamPlus(this);\n    }\n\n    public File withSuffix(String suffix)\n    {\n        if (path == null)\n            throw new IllegalStateException(\"Cannot suffix an empty path\");\n        return new File(path.getParent().resolve(path.getFileName().toString() + suffix));\n    }\n\n    private Path toPathForWrite()\n    {\n        if (path == null)\n            throw new IllegalStateException(\"Cannot write to an empty path\");\n        return path;\n    }\n\n    private Path toPathForRead()\n    {\n        if (path == null)\n            throw new IllegalStateException(\"Cannot read from an empty path\");\n        return path;\n    }\n\n    @VisibleForTesting","sourceCodeStart":768,"sourceCodeEnd":804,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/io/util/File.java#L768-L804","documentation":"File.withSuffix(suffix) appends a string to the file name (e.g. adding '.tmp' or '-CompressionInfo'). It throws IllegalStateException when the File was constructed with a null/empty path, since there is no name to suffix.","triggerScenarios":"Calling withSuffix on a File built via File.empty() or otherwise holding a null path — commonly reached indirectly through markCorrupted on an unbacked File or via absolutePath on such a File.","commonSituations":"Creating a placeholder File with the empty factory and later trying to derive sibling files; refactoring code that used to pass real paths but now passes File.empty(); descriptor code paths where a file handle was never assigned.","solutions":["Ensure the File is initialized with a real path before calling withSuffix — check where the File instance originates.","Replace File.empty() usage with a concrete path or guard the call: if (file.path() != null).","Fix the indirect caller (markCorrupted/absolutePath) to skip suffixing for pathless files."],"exampleFix":"// before\nFile corrupted = file.withSuffix(\".crc\");\n// after\nFile corrupted = file.path() == null ? null : file.withSuffix(\".crc\");\n","handlingStrategy":"type-guard","validationCode":"// before calling\nif (file.path() == null) throw new IllegalArgumentException(\"File has no path\");","typeGuard":"static boolean hasPath(File f) { return f != null && f.path() != null; }","tryCatchPattern":"try { derived = file.withSuffix(\".crc\"); }\ncatch (IllegalStateException e) { derived = null; /* pathless sentinel File */ }","preventionTips":["Don't use File.empty() as a real handle for derived names","Check file origin/initialization before path-deriving calls","Prefer Optional<File> over sentinel pathless instances"],"tags":["io","file","path","illegal-state"],"backgroundTag":"invalid-state-transition","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"}