{"record":{"id":"ebd8bd34d503387e","repo":"laurent22/joplin","slug":"could-not-create-file-at-unknownstr","errorCode":null,"errorMessage":"could not create file at: ${unknownStr}","messagePattern":"could not create file at: (.+?)","errorType":"exception","errorClass":"IOExceptionFast","httpStatus":null,"severity":"error","filePath":"packages/react-native-saf-x/android/src/main/java/com/reactnativesafx/utils/EfficientDocumentHelper.java","lineNumber":412,"sourceCode":"    try {\n      uri = getDocumentUri(unknownStr, false, true);\n    } catch (FileNotFoundException ignored) {\n    }\n\n    if (uri != null) {\n      if (replaceIfDestinationExists) return uri;\n      throw new IOExceptionFast(\"a file or directory already exist at: \" + uri);\n    }\n\n    uri = UriHelper.getUnifiedUri(unknownStr);\n\n    if (uri.getScheme().equals(ContentResolver.SCHEME_FILE)) {\n      File file = new File(uri.getPath());\n      file.getParentFile().mkdirs();\n      boolean created = file.createNewFile();\n      if (!created) {\n        if (replaceIfDestinationExists && file.exists() && file.isFile()) return uri;\n        throw new IOExceptionFast(\"could not create file at: \" + unknownStr);\n      }\n      return uri;\n    }\n\n    Uri parentDirOfFile = getDocumentUri(unknownStr, true, false);\n\n    String fileName = UriHelper.getFileName(unknownStr);\n    return createFileInDirectory(parentDirOfFile, fileName, mimeType, replaceIfDestinationExists);\n  }\n\n  private Uri createFileInDirectory(\n    final Uri parentDirOfFile,\n    final String fileName,\n    final String mimeType,\n    final boolean replaceIfDestinationExists\n  ) throws IOException {\n    if (fileName.indexOf(':') != -1) {\n      throw new IOExceptionFast(","sourceCodeStart":394,"sourceCodeEnd":430,"githubUrl":"https://github.com/laurent22/joplin/blob/981a03c5c9e88130bccff4db47c411d35ec7ae2c/packages/react-native-saf-x/android/src/main/java/com/reactnativesafx/utils/EfficientDocumentHelper.java#L394-L430","documentation":"EfficientDocumentHelper.createFile throws \"could not create file at: <path>\" when the plain file:// scheme branch fails: File.createNewFile() returned false and the replaceIfDestinationExists fallback (existing regular file) did not apply. The OS-level file creation on the local filesystem failed, typically due to permissions or an invalid/unwritable parent path.","triggerScenarios":"createFile called with a file:// URI whose createNewFile() returns false (parent dir not writable, path invalid, or file exists but is a directory) while replaceIfDestinationExists is false.","commonSituations":"Targeting app-private or restricted storage locations without permission on newer Android versions; passing a directory path as the destination; external storage not mounted.","solutions":["Use SAF content URIs (a document tree picked via openDocumentTree) instead of raw file:// paths.","Verify the parent directory exists, is writable, and the destination is not an existing directory.","Set replaceIfDestinationExists: true if the failure is due to an existing plain file."],"exampleFix":"// before\nawait SafX.createFile('file:///storage/emulated/0/notes/x.txt', 'text/plain');\n// after\nconst treeUri = await SafX.openDocumentTree();\nawait SafX.createFile(treeUri, 'x.txt', 'text/plain', { replaceIfDestinationExists: true });","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await SafX.createFile(target, mime); } catch (e) { if (String(e.message).startsWith('could not create file')) switchToSafTreeUriFlow(); }","preventionTips":["Prefer SAF content URIs from openDocumentTree over raw file:// paths on Android 10+.","Confirm the destination is not a directory and the parent path is writable."],"tags":["android","saf","filesystem","permissions"],"backgroundTag":"file-write-failed","analyzedSha":"981a03c5c9e88130bccff4db47c411d35ec7ae2c","analyzedAt":"2026-09-17T14:49:40.960Z","contentChangedAt":"2026-09-17T14:49:40.960Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}