{"record":{"id":"5c2972190aa49e9d","repo":"lingochamp/FileDownloader","slug":"can-t-generate-real-path-the-directory-is-null","errorCode":null,"errorMessage":"can't generate real path, the directory is null","messagePattern":"can't generate real path, the directory is null","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadUtils.java","lineNumber":180,"sourceCode":"\n    public static String getDefaultSaveFilePath(final String url) {\n        return generateFilePath(getDefaultSaveRootPath(), generateFileName(url));\n    }\n\n    public static String generateFileName(final String url) {\n        return md5(url);\n    }\n\n    /**\n     * @see #getTargetFilePath(String, boolean, String)\n     */\n    public static String generateFilePath(String directory, String filename) {\n        if (filename == null) {\n            throw new IllegalStateException(\"can't generate real path, the file name is null\");\n        }\n\n        if (directory == null) {\n            throw new IllegalStateException(\"can't generate real path, the directory is null\");\n        }\n\n        return formatString(\"%s%s%s\", directory, File.separator, filename);\n    }\n\n    /**\n     * The path is used as the default directory in the case of the task without set path.\n     *\n     * @param path default root path for save download file.\n     * @see com.liulishuo.filedownloader.BaseDownloadTask#setPath(String, boolean)\n     */\n    public static void setDefaultSaveRootPath(final String path) {\n        defaultSaveRootPath = path;\n    }\n\n    /**\n     * @param targetPath The target path for the download task.\n     * @return The temp path is {@code targetPath} in downloading status; The temp path is used for","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/lingochamp/FileDownloader/blob/6237a8cac174bcc916e4342b14ab1ab72a5768d4/library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadUtils.java#L162-L198","documentation":"generateFilePath requires a non-null directory to compose '<directory><separator><filename>'. A null directory means the target storage location is unknown, so the library throws IllegalStateException rather than writing to an unpredictable location.","triggerScenarios":"Calling FileDownloadUtils.generateFilePath(null, filename), or getDefaultSaveFilePath with a null directory (e.g. FileDownloadUtils.getDefaultSaveDirectory() returned null because the custom save directory was never initialized).","commonSituations":"Using a custom download directory before FileDownloader.setupOnWriteOver() / context is ready; passing the result of a method that returns null when external storage path resolution fails; unit tests calling the util with a stubbed directory.","solutions":["Pass a valid directory, e.g. FileDownloadUtils.getDefaultSaveDirectory() or context.getExternalFilesDir(null).getAbsolutePath().","Initialize the default download directory (FileDownloadUtils.setDefaultSaveRootPath or let the library set it up with an app context) before generating paths.","Null-check the directory at the call site and fall back to the default save directory."],"exampleFix":"// before\nString path = FileDownloadUtils.generateFilePath(null, \"file.zip\");\n\n// after\nString dir = customDir != null ? customDir : FileDownloadUtils.getDefaultSaveDirectory();\nString path = FileDownloadUtils.generateFilePath(dir, \"file.zip\");","handlingStrategy":"type-guard","validationCode":"if (directory == null) {\n    directory = FileDownloadUtils.getDefaultSaveDirectory();\n}\nString path = FileDownloadUtils.generateFilePath(directory, filename);","typeGuard":"boolean hasDirectory(String d) { return d != null && new File(d).isDirectory(); }","tryCatchPattern":"try {\n    return FileDownloadUtils.generateFilePath(directory, filename);\n} catch (IllegalStateException e) {\n    return FileDownloadUtils.generateFilePath(FileDownloadUtils.getDefaultSaveDirectory(), filename);\n}","preventionTips":["Initialize the download root path early (Application.onCreate) before generating paths.","Resolve directories with context.getExternalFilesDir(...) and null-check the result.","Keep one helper method that returns a validated default directory for all call sites."],"tags":["android","null-argument","path-generation","filedownloader"],"backgroundTag":"null-argument","analyzedSha":"6237a8cac174bcc916e4342b14ab1ab72a5768d4","analyzedAt":"2026-09-08T23:50:48.168Z","contentChangedAt":"2026-09-08T23:50:48.168Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}