{"record":{"id":"d89a98d695f2612d","repo":"apache/cassandra","slug":"root-level-resource-can-t-have-a-parent","errorCode":null,"errorMessage":"Root-level resource can't have a parent","messagePattern":"Root-level resource can't have a parent","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/auth/DataResource.java","lineNumber":193,"sourceCode":"        }\n        throw new AssertionError();\n    }\n\n    /**\n     * @return Parent of the resource, if any. Throws IllegalStateException if it's the root-level resource.\n     */\n    public IResource getParent()\n    {\n        switch (level)\n        {\n            case KEYSPACE:\n                return root();\n            case ALL_TABLES:\n                return keyspace(keyspace);\n            case TABLE:\n                return allTables(keyspace);\n        }\n        throw new IllegalStateException(\"Root-level resource can't have a parent\");\n    }\n\n    public boolean isRootLevel()\n    {\n        return level == Level.ROOT;\n    }\n\n    public boolean isKeyspaceLevel()\n    {\n        return level == Level.KEYSPACE;\n    }\n\n    public boolean isAllTablesLevel()\n    {\n        return level == Level.ALL_TABLES;\n    }\n\n    public boolean isTableLevel()","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/auth/DataResource.java#L175-L211","documentation":"DataResource.getParent walks up the resource hierarchy (table -> keyspace's all-tables -> keyspace -> root). The switch is exhaustive over non-root levels, so reaching the fall-through means getParent was called on the ROOT resource, which has no parent; an IllegalStateException is thrown as an internal invariant guard.","triggerScenarios":"Calling DataResource.getParent() on DataResource.root(); generic code that traverses parent chains of arbitrary resources without first checking isRootLevel().","commonSituations":"Permission-hierarchy walkers that recurse up to the root and then call getParent once more; code assuming at least one parent exists for every resource.","solutions":["Guard with if (!resource.isRootLevel()) before calling getParent()","Stop the parent traversal when isRootLevel() returns true","Use the level accessor to branch on Level.ROOT explicitly"],"exampleFix":"// before\nfor (DataResource r = res; r != null; r = r.getParent()) {...}\n// after\nfor (DataResource r = res; r != null; r = r.isRootLevel() ? null : r.getParent()) {...}","handlingStrategy":"type-guard","validationCode":"boolean hasParent(DataResource r) { return !r.isRootLevel(); }","typeGuard":"DataResource parentOrNull(DataResource r) { return r.isRootLevel() ? null : r.getParent(); }","tryCatchPattern":"try { parent = r.getParent(); } catch (IllegalStateException e) { parent = null; /* r is root */ }","preventionTips":["Check isRootLevel() before calling getParent()","Terminate hierarchy traversals at the root level","Treat ROOT as the anchor of the parent chain, never a child"],"tags":["cassandra","auth","illegal-state","resource-hierarchy"],"backgroundTag":"invalid-state-transition","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}