{"record":{"id":"4d6538f2b87d55eb","repo":"libgdx/libgdx","slug":"cannot-get-the-sibling-of-the-root-4d6538","errorCode":null,"errorMessage":"Cannot get the sibling of the root.","messagePattern":"Cannot get the sibling of the root\\.","errorType":"validation","errorClass":"GdxRuntimeException","httpStatus":null,"severity":"error","filePath":"backends/gdx-backend-robovm-metalangle/src/com/badlogic/gdx/backends/iosrobovm/IOSFileHandle.java","lineNumber":41,"sourceCode":"\t\tif (file.getPath().length() == 0) return new IOSFileHandle(new File(name), type);\n\t\treturn new IOSFileHandle(new File(file, name), type);\n\t}\n\n\t@Override\n\tpublic FileHandle parent () {\n\t\tFile parent = file.getParentFile();\n\t\tif (parent == null) {\n\t\t\tif (type == FileType.Absolute)\n\t\t\t\tparent = new File(\"/\");\n\t\t\telse\n\t\t\t\tparent = new File(\"\");\n\t\t}\n\t\treturn new IOSFileHandle(parent, type);\n\t}\n\n\t@Override\n\tpublic FileHandle sibling (String name) {\n\t\tif (file.getPath().length() == 0) throw new GdxRuntimeException(\"Cannot get the sibling of the root.\");\n\t\treturn new IOSFileHandle(new File(file.getParent(), name), type);\n\t}\n\n\t@Override\n\tpublic File file () {\n\t\tif (type == FileType.Internal) return new File(IOSFiles.internalPath, file.getPath());\n\t\tif (type == FileType.External) return new File(IOSFiles.externalPath, file.getPath());\n\t\tif (type == FileType.Local) return new File(IOSFiles.localPath, file.getPath());\n\t\treturn file;\n\t}\n}\n","sourceCodeStart":23,"sourceCodeEnd":53,"githubUrl":"https://github.com/libgdx/libgdx/blob/97f40861878058087be0685ca167ddfde132134b/backends/gdx-backend-robovm-metalangle/src/com/badlogic/gdx/backends/iosrobovm/IOSFileHandle.java#L23-L53","documentation":"IOSFileHandle.sibling(name) refuses to build a sibling path when the current file's path is empty (length 0), i.e. the handle represents the root itself — a root has no parent directory, so a sibling is undefined. The Android/desktop backends share this semantics; only the message is iOS-specific.","triggerScenarios":"Calling sibling(...) on a FileHandle constructed from an empty path string, e.g. new IOSFileHandle(\"\", type).sibling(\"x\"), or code that walks up to root via parent() and then calls sibling().","commonSituations":"Path-manipulation utilities that call parent() repeatedly then sibling() at the top; constructing handles from user input where the empty string slips through; relative-path handling that normalizes to empty.","solutions":["Guard the call: skip or special-case when the handle path is empty.","Fix upstream logic so sibling() is only invoked on non-root handles (check file.getPath().length() > 0 first).","If you intended a child of root, use child(name) instead of sibling(name)."],"exampleFix":"// before\nFileHandle next = dir.sibling(\"save.dat\"); // throws if dir is root\n// after\nFileHandle next = dir.file.getPath().length() == 0 ? dir.child(\"save.dat\") : dir.sibling(\"save.dat\");","handlingStrategy":"type-guard","validationCode":"if (dir.file.getPath().length() == 0) { /* at root: no sibling exists */ }","typeGuard":"static boolean hasSibling(FileHandle h) { return h.file.getPath().length() > 0; }","tryCatchPattern":null,"preventionTips":["Use child() when you mean 'under root'.","Bound parent()-walking loops before reaching the empty root path."],"tags":["ios","libgdx","files","path","robovm"],"backgroundTag":null,"analyzedSha":"97f40861878058087be0685ca167ddfde132134b","analyzedAt":"2026-08-14T10:52:53.492Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}