{"record":{"id":"dd0337f2e7caf6e5","repo":"alibaba/arthas","slug":"failed-to-create-mcp-upload-directory","errorCode":null,"errorMessage":"Failed to create MCP upload directory","messagePattern":"Failed to create MCP upload directory","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"critical","filePath":"core/src/main/java/com/taobao/arthas/core/mcp/tool/function/basic1000/UploadFileTool.java","lineNumber":370,"sourceCode":"                throw new IllegalArgumentException(\"uploadRoot must not be a symbolic link\");\n            }\n            Files.createDirectories(normalized);\n            if (!Files.isDirectory(normalized, LinkOption.NOFOLLOW_LINKS)) {\n                throw new IllegalArgumentException(\"uploadRoot must be a directory\");\n            }\n            Path realRoot = normalized.toRealPath();\n            setDirectoryPermissions(realRoot);\n            return realRoot;\n        } catch (IOException e) {\n            throw new IllegalStateException(\"Failed to prepare MCP upload directory\", e);\n        }\n    }\n\n    private static Path createDefaultUploadRoot() {\n        try {\n            return Files.createTempDirectory(\"arthas-mcp-uploads-\");\n        } catch (IOException e) {\n            throw new IllegalStateException(\"Failed to create MCP upload directory\", e);\n        }\n    }\n\n    private static void setDirectoryPermissions(Path directory) throws IOException {\n        try {\n            Files.setPosixFilePermissions(directory, DIRECTORY_PERMISSIONS);\n        } catch (UnsupportedOperationException ignored) {\n            // 当前文件系统不支持 POSIX 权限。\n        }\n    }\n\n    private static void setFilePermissions(Path file) throws IOException {\n        try {\n            Files.setPosixFilePermissions(file, FILE_PERMISSIONS);\n        } catch (UnsupportedOperationException ignored) {\n            // 当前文件系统不支持 POSIX 权限。\n        }\n    }","sourceCodeStart":352,"sourceCodeEnd":388,"githubUrl":"https://github.com/alibaba/arthas/blob/21cf2e9ba52b305290be7223b980ff504bb9cb5b/core/src/main/java/com/taobao/arthas/core/mcp/tool/function/basic1000/UploadFileTool.java#L352-L388","documentation":"createDefaultUploadRoot fails when Files.createTempDirectory(\"arthas-mcp-uploads-\") throws IOException. This method runs inside a static initializer (DefaultUploadRootHolder class at line 447-449), so a failure here causes an ExceptionInInitializerError at class-load time, preventing UploadFileTool from being used at all.","triggerScenarios":"The JVM's temp directory (java.io.tmpdir, typically /tmp) is full, read-only, or inaccessible when the UploadFileTool class is first loaded and the static initializer runs.","commonSituations":"Disk full in /tmp; container has a read-only tmpfs at /tmp; tmpdir permissions changed after JVM start; no space left on device; /tmp mounted noexec or with insufficient inode quota.","solutions":["Ensure java.io.tmpdir is writable and has free space and inodes.","Start the JVM with -Djava.io.tmpdir=/path/to/writable/dir to redirect temp files.","Clean up disk space or old temp files in the current tmpdir.","Fix filesystem mount options (read-write) for the temp directory."],"exampleFix":"// before: JVM started with default tmpdir that is full or read-only\njava -jar arthas-boot.jar\n// after: redirect tmpdir to a writable location with space\njava -Djava.io.tmpdir=/data/tmp -jar arthas-boot.jar","handlingStrategy":"try-catch","validationCode":"// Before class-load, verify java.io.tmpdir is writable\nPath tmp = Paths.get(System.getProperty(\"java.io.tmpdir\"));\nPath testFile = tmp.resolve(\"arthas-mcp-upload-probe-\" + System.nanoTime());\ntry {\n    Files.createDirectories(tmp);\n    Files.createFile(testFile);\n    Files.delete(testFile);\n} catch (IOException e) {\n    throw new IllegalStateException(\n        \"Temp directory is not writable: \" + tmp + \" — set -Djava.io.tmpdir\", e);\n}","typeGuard":null,"tryCatchPattern":"// This fires in a static initializer; catch at the JVM level is limited.\n// Prevent it by validating tmpdir before the class loads:\ntry {\n    Class.forName(\"com.taobao.arthas.core.mcp.tool.function.basic1000.UploadFileTool\");\n} catch (ExceptionInInitializerError e) {\n    if (e.getCause() instanceof IllegalStateException\n            && e.getCause().getMessage().contains(\"Failed to create MCP upload directory\")) {\n        // tmpdir is full or read-only — restart with -Djava.io.tmpdir=/writable/dir\n    }\n}","preventionTips":["Start the JVM with -Djava.io.tmpdir pointing to a writable directory with sufficient space.","Monitor disk space on /tmp in containers and CI environments.","Clean up stale temp files regularly.","Verify tmpdir writability in a startup health check before loading UploadFileTool."],"tags":["upload","filesystem","initialization","temp-dir","io","arthas-mcp"],"backgroundTag":null,"analyzedSha":"21cf2e9ba52b305290be7223b980ff504bb9cb5b","analyzedAt":"2026-08-14T00:57:07.243Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}