{"record":{"id":"156128a977d7a82b","repo":"apache/cassandra","slug":"root-data-resource-has-no-keyspace","errorCode":null,"errorMessage":"ROOT data resource has no keyspace","messagePattern":"ROOT data resource has no keyspace","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/auth/DataResource.java","lineNumber":221,"sourceCode":"        return level == Level.KEYSPACE;\n    }\n\n    public boolean isAllTablesLevel()\n    {\n        return level == Level.ALL_TABLES;\n    }\n\n    public boolean isTableLevel()\n    {\n        return level == Level.TABLE;\n    }\n    /**\n     * @return keyspace of the resource. Throws IllegalStateException if it's the root-level resource.\n     */\n    public String getKeyspace()\n    {\n        if (isRootLevel())\n            throw new IllegalStateException(\"ROOT data resource has no keyspace\");\n        return keyspace;\n    }\n\n    /**\n     * @return column family of the resource. Throws IllegalStateException if it's not a table-level resource.\n     */\n    public String getTable()\n    {\n        if (!isTableLevel())\n            throw new IllegalStateException(String.format(\"%s data resource has no table\", level));\n        return table;\n    }\n\n    /**\n     * @return Whether or not the resource has a parent in the hierarchy.\n     */\n    public boolean hasParent()\n    {","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/auth/DataResource.java#L203-L239","documentation":"DataResource.getKeyspace returns the keyspace component only for non-root resources (all-keyspaces/all-tables/table levels). Calling it on the ROOT resource is invalid — there is no keyspace — so it throws IllegalStateException.","triggerScenarios":"Calling getKeyspace() on DataResource.root(); generic permission-checking or logging code that extracts the keyspace from any DataResource without checking isRootLevel(); existing callers listed include maybeCorrectResource, validate, and keyspace().","commonSituations":"Functions that receive resources from LIST PERMISSIONS output spanning all levels and unconditionally call getKeyspace; refactoring where a ROOT case was not added to a switch.","solutions":["Check !resource.isRootLevel() (or level != Level.ROOT) before calling getKeyspace()","Branch on resource level and handle ROOT separately","If you need an optional keyspace, wrap with the level check and return null/Optional.empty for root"],"exampleFix":"// before\nString ks = resource.getKeyspace();\n// after\nString ks = resource.isRootLevel() ? null : resource.getKeyspace();","handlingStrategy":"type-guard","validationCode":"boolean hasKeyspace(DataResource r) { return !r.isRootLevel(); }","typeGuard":"String keyspaceOrNull(DataResource r) { return r.isRootLevel() ? null : r.getKeyspace(); }","tryCatchPattern":"try { ks = r.getKeyspace(); } catch (IllegalStateException e) { ks = null; /* r is ROOT */ }","preventionTips":["Check isRootLevel() before calling getKeyspace()","Handle Level.ROOT explicitly in switches over resource levels","Avoid getKeyspace() on resources of unknown provenance (e.g. permission listings) without a level check"],"tags":["cassandra","auth","illegal-state","resource-level"],"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"}