{"record":{"id":"e5b9002a9f10c444","repo":"vitessio/vitess","slug":"err-e5b900","errorCode":null,"errorMessage":"err","messagePattern":"err","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtgate/planbuilder/operators/delete.go","lineNumber":84,"sourceCode":"\t// We check if delete with input plan is required. DML with input planning is generally\n\t// slower, because it does a selection and then creates a delete statement wherein we have to\n\t// list all the primary key values.\n\tif deleteWithInputPlanningRequired(childFks, deleteStmt) {\n\t\treturn createDeleteWithInputOp(ctx, deleteStmt)\n\t}\n\n\tdelClone := sqlparser.Clone(deleteStmt)\n\tvar vTbl *vindexes.BaseTable\n\top, vTbl = createDeleteOperator(ctx, deleteStmt)\n\n\tif deleteStmt.Comments != nil {\n\t\top = newLockAndComment(op, deleteStmt.Comments, sqlparser.NoLock)\n\t}\n\n\tvar err error\n\tchildFks, err = ctx.SemTable.GetChildForeignKeysForTable(deleteStmt.Targets[0])\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\t// If there are no foreign key constraints, then we don't need to do anything special.\n\tif len(childFks) == 0 {\n\t\treturn op\n\t}\n\n\treturn createFkCascadeOpForDelete(ctx, op, delClone, childFks, vTbl)\n}\n\nfunc deleteWithInputPlanningRequired(childFks []vindexes.ChildFKInfo, deleteStmt *sqlparser.Delete) bool {\n\tif len(deleteStmt.Targets) > 1 {\n\t\treturn true\n\t}\n\t// If there are no foreign keys, we don't need to use delete with input.\n\tif len(childFks) == 0 {\n\t\treturn false\n\t}\n\t// Limit requires delete with input.","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtgate/planbuilder/operators/delete.go#L66-L102","documentation":"During DELETE query planning, Vitess calls SemTable.GetChildForeignKeysForTable to discover child foreign-key constraints pointing at the delete target. If semantic analysis cannot resolve the target table (because the table was not found, is ambiguous, or the delete targets a table it cannot resolve to a single TableSet), the returned error is re-panicked so planning aborts. The error text is whatever the semantic layer produced, typically a 'table not found' or ambiguous-table message.","triggerScenarios":"DELETE on a table whose target cannot be resolved by the semantic table during createOperatorFromDelete, e.g. DELETE against a non-existent/unqualified table that fails resolution, or after GetTargetTableSetForTableName succeeded earlier but GetChildForeignKeysForTable can't map deleteStmt.Targets[0] to table info.","commonSituations":"Running a DELETE with a multi-table or aliased target that semantic analysis resolved inconsistently; keyspace/table naming mistakes in the DELETE statement; querying a table removed from the vschema while sessions still reference it; hitting an internal planner bug where targets and table-set bookkeeping disagree.","solutions":["Verify the DELETE targets a single, correctly keyspace-qualified table that exists in the vschema (SHOW VSCHEMA TABLES / check vschema JSON).","Simplify the DELETE: remove multi-table targets and run one DELETE per table.","Check the underlying error message in the panic for 'not found' vs 'ambiguous' and fix the table name or qualification accordingly.","If the table exists and the query is simple, capture the exact SQL and file an issue with the Vitess version — this is likely a planner bug."],"exampleFix":"// before (failing)\nDELETE FROM unknown_table WHERE id = 1;\n\n// after (fix: qualify and ensure table is in vschema)\nDELETE FROM commerce.orders WHERE id = 1;","handlingStrategy":"validation","validationCode":"// before issuing DELETE in app code\nif !keyspaceHasTable(keyspace, \"orders\") {\n    return fmt.Errorf(\"table %s.%s not found in vschema\", keyspace, \"orders\")\n}\nif strings.Contains(strings.ToLower(sql), \"delete\") && countDeleteTargets(sql) > 1 {\n    return errors.New(\"split multi-table deletes into single-table statements\")\n}","typeGuard":"func tableExistsInVschema(t *sqlparser.TableName, vs map[string]interface{}) bool {\n    return vs[t.Qualifier.String()+\".\"+t.Name.String()] != nil || vs[t.Name.String()] != nil\n}","tryCatchPattern":"// Vitess returns panics as errors to clients; handle on the client\nres, err := vtgateExec(ctx, sql)\nif err != nil {\n    if strings.Contains(err.Error(), \"not found\") {\n        return recoverMissingTable(err) // verify name/vschema, then retry\n    }\n    return err\n}","preventionTips":["Always keyspace-qualify table names in DML","Keep vschema and DDL in sync via a migration pipeline","Avoid multi-table DELETE syntax against sharded keyspaces","Add integration tests that run every DML statement shape against a test keyspace"],"tags":["vitess","planbuilder","delete","table-resolution"],"backgroundTag":"table-not-found-in-vschema","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}