{"record":{"id":"796f36b04a26e4b2","repo":"alibaba/arthas","slug":"filepath-is-a-directory","errorCode":null,"errorMessage":"${filePath}: Is a directory","messagePattern":"(.+?): Is a directory","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/com/taobao/arthas/core/shell/command/internal/TeeHandler.java","lineNumber":28,"sourceCode":"import java.io.*;\nimport java.util.List;\n\n/**\n * @author min.yang\n */\npublic class TeeHandler extends StdoutHandler implements CloseFunction {\n    public static final String NAME = \"tee\";\n    private PrintWriter out;\n    private static CLI cli = null;\n\n    public TeeHandler(String filePath, boolean append) throws IOException {\n        if (StringUtils.isEmpty(filePath)) {\n            return;\n        }\n        File file = new File(filePath);\n\n        if (file.isDirectory()) {\n            throw new IOException(filePath + \": Is a directory\");\n        }\n\n        if (!file.exists()) {\n            File parentFile = file.getParentFile();\n            if (parentFile != null) {\n                parentFile.mkdirs();\n            }\n        }\n        out = new PrintWriter(new BufferedWriter(new FileWriter(file, append)));\n    }\n\n    public static StdoutHandler inject(List<CliToken> tokens) {\n        List<String> args = StdoutHandler.parseArgs(tokens, NAME);\n\n        TeeCommand teeCommand = new TeeCommand();\n        if (cli == null) {\n            cli = CLIConfigurator.define(TeeCommand.class);\n        }","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/alibaba/arthas/blob/21cf2e9ba52b305290be7223b980ff504bb9cb5b/core/src/main/java/com/taobao/arthas/core/shell/command/internal/TeeHandler.java#L10-L46","documentation":"The tee output handler (for '| tee <path>') refuses to open a path that is an existing directory, matching standard tee behavior. It throws IOException before attempting FileWriter creation.","triggerScenarios":"Using the tee pipe in an Arthas shell command (e.g., 'thread | tee /tmp') where the target path is an existing directory. Note: if filePath is empty the constructor silently returns without error (line 22-24).","commonSituations":"User specifies a directory path as the tee target; trailing slash; directory name collision; empty path is silently ignored so the error only fires for a non-empty directory path.","solutions":["Specify a file path for the tee output.","Append a filename to the directory path.","Remove trailing slashes."],"exampleFix":"// before (in Arthas shell)\nthread | tee /tmp\n// after\nthread | tee /tmp/thread-dump.txt","handlingStrategy":"validation","validationCode":"// Before constructing TeeHandler, check the target is not a directory\nif (filePath != null && !filePath.isEmpty()) {\n    File f = new File(filePath);\n    if (f.isDirectory()) {\n        throw new IOException(filePath + \": Is a directory — specify a file path\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    TeeHandler handler = new TeeHandler(filePath, append);\n} catch (IOException e) {\n    if (e.getMessage().endsWith(\": Is a directory\")) {\n        // tee target is a directory — ask user for a file path\n    }\n}","preventionTips":["Always specify a file path for tee output in Arthas shell commands.","Remove trailing slashes from the tee target.","Note: an empty filePath is silently ignored (no error), so verify non-empty paths."],"tags":["shell","tee","filesystem","arthas"],"backgroundTag":null,"analyzedSha":"21cf2e9ba52b305290be7223b980ff504bb9cb5b","analyzedAt":"2026-08-14T00:57:07.243Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}