{"record":{"id":"10980f9e09fb047b","repo":"apache/shardingsphere","slug":"4","errorCode":"4","errorMessage":"Actual table '%s.%s' is not in table rule configuration.","messagePattern":"Actual table '(.+?)\\.(.+?)' is not in table rule configuration\\.","errorType":"exception","errorClass":"ActualTableNotFoundException","httpStatus":null,"severity":"error","filePath":"features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/BindingTableRule.java","lineNumber":67,"sourceCode":"        return shardingTables.containsKey(logicTable);\n    }\n    \n    /**\n     * Deduce actual table name from other actual table name in same binding table rule.\n     *\n     * @param dataSource data source name\n     * @param logicTable logic table name\n     * @param otherLogicTable other logic table name in same binding table rule\n     * @param otherActualTable other actual table name in same binding table rule\n     * @return actual table name\n     * @throws ActualTableNotFoundException actual table not found exception\n     * @throws BindingTableNotFoundException binding table not found exception\n     */\n    public String getBindingActualTable(final String dataSource, final String logicTable, final String otherLogicTable, final String otherActualTable) {\n        Optional<ShardingTable> otherShardingTable = Optional.ofNullable(shardingTables.get(otherLogicTable));\n        int index = otherShardingTable.map(optional -> optional.findActualTableIndex(dataSource, otherActualTable)).orElse(-1);\n        if (-1 == index) {\n            throw new ActualTableNotFoundException(dataSource, otherActualTable);\n        }\n        Optional<ShardingTable> shardingTable = Optional.ofNullable(shardingTables.get(logicTable));\n        if (shardingTable.isPresent()) {\n            return shardingTable.get().getActualDataNodes().get(index).getTableName();\n        }\n        throw new BindingTableNotFoundException(dataSource, logicTable, otherActualTable);\n    }\n    \n    /**\n     * Get list of logical table.\n     *\n     * @return logical tables.\n     */\n    public Collection<String> getAllLogicTables() {\n        return shardingTables.keySet();\n    }\n    \n    /**","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/apache/shardingsphere/blob/e952770a215630a3659c75d64369168cd3e26b82/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rule/BindingTableRule.java#L49-L85","documentation":"ActualTableNotFoundException is thrown by BindingTableRule.getBindingActualTable when the 'other' table in a binding group has no actual table at the given data source: otherShardingTable.findActualTableIndex(dataSource, otherActualTable) returns -1 (table absent or otherLogicTable unknown), so the index into the bound table's actual data nodes cannot be computed. It signals that a routed actual table of one binding member does not exist in the configuration of the member being resolved.","triggerScenarios":"Binding-table routing resolves the actual table for a second table in the group from a first table's (dataSource, actualTable); the first table's actual table is not present in its own rule for that data source — mismatched actualDataNodes between tables in one binding group, or an unknown otherLogicTable.","commonSituations":"Binding tables (BOUND TABLE TABLES t_order, t_order_item) configured with different table counts or different data source sets; adding a table to a binding group before aligning its topology; stale metadata after DistSQL rule changes.","solutions":["Give every table in the binding group identical topology: same data sources and same actual table count per data source.","Verify the binding group members with SHOW SHARDING BINDING TABLE RULES and remove/fix entries whose actualDataNodes differ.","Refresh metadata (or restart) after rule changes so binding rules are rebuilt from consistent configuration."],"exampleFix":"-- before: members of one binding group differ\nCREATE SHARDING BINDING TABLE RULES (t_order, t_order_item);\nt_order:      ds_${0..1}.t_order_${0..3}\nt_order_item: ds_0.t_order_item_0\n\n-- after: aligned\nCREATE SHARDING BINDING TABLE RULES (t_order, t_order_item);\nt_order:      ds_${0..1}.t_order_${0..3}\nt_order_item: ds_${0..1}.t_order_item_${0..3}","handlingStrategy":"validation","validationCode":"// Validate binding-group topology symmetry before enabling a binding rule\nboolean symmetric(ShardingTable a, ShardingTable b) {\n    Map<String, Long> ma = a.getActualDataNodes().stream().collect(groupingBy(DataNode::getDataSourceName, counting()));\n    Map<String, Long> mb = b.getActualDataNodes().stream().collect(groupingBy(DataNode::getDataSourceName, counting()));\n    return ma.equals(mb);\n}","typeGuard":null,"tryCatchPattern":"try {\n    rs = stmt.executeQuery(joinSql);\n} catch (final ActualTableNotFoundException ex) {\n    // message shows ds + actual table; repair that table's actualDataNodes and retry\n}","preventionTips":["Only bind tables with identical data source sets and per-data-source table counts.","Automate a topology-symmetry check in CI for binding table groups."],"tags":["sharding","binding-table","routing","configuration","topology"],"backgroundTag":null,"analyzedSha":"e952770a215630a3659c75d64369168cd3e26b82","analyzedAt":"2026-08-14T13:54:53.392Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}