vitessio/vitess · error

VT13001

VT13001

Error message

a derived table should never be a routed table

What it means

VT13001 is Vitess' internal-error code. While rewriting a routed table reference, the planner expects the query table's alias expression to be a plain TableName; if it is a derived table (subquery in FROM), that invariant is broken, meaning a routed table is being defined via a derived table expression — never valid.

Source

Thrown at go/vt/vtgate/planbuilder/operators/route.go:450

	return nil
}

// createRouteFromTable creates a route from the given VSchema table.
func createRouteFromVSchemaTable(
	ctx *plancontext.PlanningContext,
	queryTable *QueryTable,
	vschemaTable *vindexes.BaseTable,
	planAlternates bool,
	targeted Routing,
) *Route {
	if vschemaTable.Name.String() != queryTable.Table.Name.String() {
		// we are dealing with a routed table
		queryTable = queryTable.Clone()
		name := queryTable.Table.Name
		queryTable.Table.Name = vschemaTable.Name
		astTable, ok := queryTable.Alias.Expr.(sqlparser.TableName)
		if !ok {
			panic(vterrors.VT13001("a derived table should never be a routed table"))
		}
		realTableName := sqlparser.NewIdentifierCS(vschemaTable.Name.String())
		astTable.Name = realTableName
		if queryTable.Alias.As.IsEmpty() {
			// if the user hasn't specified an alias, we'll insert one here so the old table name still works
			queryTable.Alias.As = sqlparser.NewIdentifierCS(name.String())
		}
	}
	plan := &Route{
		unaryOperator: newUnaryOp(&Table{
			QTable: queryTable,
			VTable: vschemaTable,
		}),
	}

	// We create the appropriate Routing struct here, depending on the type of table we are dealing with.
	var routing Routing
	if targeted != nil {

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Check the vschema: the routed table's target should be a real table, not something resolvable through a derived table
  2. Rewrite the query to reference the underlying table directly instead of via a subquery alias
  3. File a bug with query + vschema if this occurs with a valid configuration

Example fix

// vschema before
"route_target": {"type": "routed", "target": "..."} // resolves via subquery
// after
"real_table": {"type": "routed", "target": "ks.real_table"} // point at a concrete table
Defensive patterns

Strategy: validation

Validate before calling

// validate vschema routed tables resolve to concrete tables, not subquery aliases
// before deploying, run the query through vtexplain / vtgate with the vschema

Prevention

When it happens

Trigger: A vschema defines a routed table whose resolution path encounters a derived-table (aliased subquery) AST node instead of a TableName in createRouteFromVSchemaTable.

Common situations: Misconfigured vschema routed_table entries conflicting with subquery-based queries; planner bugs where a routed table resolves through a derived table.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/76fc69192b4206d2. Report an issue: GitHub.