MyCATApache/Mycat-Server · error · RuntimeException
please make sure the primaryKey's config is not null in…
Error message
please make sure the primaryKey's config is not null in schemal.xml
What it means
isPKInFields parses an INSERT's column list to locate the primary key's position, but the primaryKey argument itself is null because the table's configuration lacks a primaryKey. The method throws RuntimeException immediately since primary-key-based routing cannot proceed without it. Note the message says 'schemal.xml' but it refers to schema.xml.
Solutions
- Add primaryKey="<column>" to the table's <table> definition in schema.xml and reload the config
- If PK routing is not needed, ensure the insert routing path does not rely on primaryKey (e.g. configure a proper sharding rule on an existing column)
- Update the code/config so the table uses childTable/parent key routing only when the parent's primaryKey is defined
Example fix
// before (schema.xml) <table name="t_order" dataNode="dn1,dn2" rule="mod-rule"/> // after <table name="t_order" dataNode="dn1,dn2" rule="mod-rule" primaryKey="id"/>
Defensive patterns
Strategy: validation
Validate before calling
TableConfig tc = schema.getTables().get(tableName);
if (tc == null || tc.getPrimaryKey() == null || tc.getPrimaryKey().isEmpty()) {
throw new IllegalStateException("table " + tableName + " needs primaryKey in schema.xml");
} Try / catch
try { routeInsert(...); } catch (RuntimeException e) { if (e.getMessage().contains("primaryKey")) { /* fix schema.xml */ } throw e; } Prevention
- Always set primaryKey on sharded and ER child-table parents
- Add schema.xml linting in CI
- Reload and test config after every table addition
When it happens
Trigger: Executing an INSERT against a sharded table that uses the primary key for routing (or child-table join-key logic) while the <table> entry in schema.xml has no primaryKey attribute, and code path routeToMultiNode...insert calls isPKInFields with tableConfig.getPrimaryKey() == null.
Common situations: Declaring a sharded <table> with rule based on a column but omitting primaryKey="id"; after adding a new table to schema.xml without the primaryKey attribute; autoincrement/sequence features requiring PK not configured.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- op table not in schema
- can't find table define in schema
- can't find table define in schema
- can't find table define in schema
- Can't find a valid data node for specified node index
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/9b43b206f2c616a4.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/route/util/RouterUtil.java:610
String origSQL, ServerConnection sc) throws SQLNonTransientException {
String tableName = StringUtil.getTableName(origSQL).toUpperCase();
TableConfig tableConfig = schema.getTables().get(tableName);
boolean processedInsert=false;
//判断是有自增字段
if (null != tableConfig && tableConfig.isAutoIncrement()) {
String primaryKey = tableConfig.getPrimaryKey();
processedInsert=processInsert(sc,schema,sqlType,origSQL,tableName,primaryKey);
}
return processedInsert;
}
/*
* 找到返回主键的的位置
* 找不到返回 -1
* */
private static int isPKInFields(String origSQL,String primaryKey,int firstLeftBracketIndex,int firstRightBracketIndex){
if (primaryKey == null) {
throw new RuntimeException("please make sure the primaryKey's config is not null in schemal.xml");
}
boolean isPrimaryKeyInFields = false;
int pkStart = 0;
String upperSQL = origSQL.substring(firstLeftBracketIndex, firstRightBracketIndex + 1).toUpperCase();
for (int pkOffset = 0, primaryKeyLength = primaryKey.length();;) {
pkStart = upperSQL.indexOf(primaryKey, pkOffset);
if (pkStart >= 0 && pkStart < firstRightBracketIndex) {
char pkSide = upperSQL.charAt(pkStart - 1);
if (pkSide <= ' ' || pkSide == '`' || pkSide == ',' || pkSide == '(') {
pkSide = upperSQL.charAt(pkStart + primaryKey.length());
isPrimaryKeyInFields = pkSide <= ' ' || pkSide == '`' || pkSide == ',' || pkSide == ')';
}
if (isPrimaryKeyInFields) {
break;
}
pkOffset = pkStart + primaryKeyLength;
} else {
View on GitHub (pinned to 65f8d8beb7)