{"record":{"id":"f95bc475a6785924","repo":"vitessio/vitess","slug":"plan-not-found-for-table-s-current-plans-are","errorCode":null,"errorMessage":"plan not found for table: %s, current plans are: %#v","messagePattern":"plan not found for table: (.+?), current plans are: %#v","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vttablet/tabletmanager/vreplication/vcopier.go","lineNumber":395,"sourceCode":"\n// copyTable performs the synchronized copy of the next set of rows from\n// the current table being copied. Each packet received is transactionally\n// committed with the lastpk. This allows for consistent resumability.\nfunc (vc *vcopier) copyTable(ctx context.Context, tableName string, copyState map[string]*sqltypes.Result) error {\n\tdefer vc.vr.dbClient.Rollback()\n\tdefer vc.vr.stats.PhaseTimings.Record(\"copy\", time.Now())\n\tdefer vc.vr.stats.CopyLoopCount.Add(1)\n\n\tlog.Info(fmt.Sprintf(\"Copying table %s, lastpk: %v\", tableName, copyState[tableName]))\n\n\tplan, err := vc.vr.buildReplicatorPlan(vc.vr.source, vc.vr.colInfoMap, nil, vc.vr.stats, vc.vr.vre.env.CollationEnv(), vc.vr.vre.env.Parser())\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tinitialPlan, ok := plan.TargetTables[tableName]\n\tif !ok {\n\t\treturn fmt.Errorf(\"plan not found for table: %s, current plans are: %#v\", tableName, plan.TargetTables)\n\t}\n\n\t// Save the controller-level context before applying the copy phase\n\t// duration timeout to it. Its cancellation means that the controller\n\t// is stopping -- because the workflow is being stopped or deleted, or\n\t// the engine is closing -- and any in-flight post copy action must\n\t// then be interrupted, whereas an elapsed copy phase duration must\n\t// not interrupt it.\n\tstopCtx := ctx\n\tctx, cancel := context.WithTimeout(ctx, vc.vr.workflowConfig.CopyPhaseDuration)\n\tdefer cancel()\n\n\tvar lastpkpb *querypb.QueryResult\n\tif lastpkqr := copyState[tableName]; lastpkqr != nil {\n\t\tlastpkpb = sqltypes.ResultToProto3(lastpkqr)\n\t}\n\n\trowsCopiedTicker := time.NewTicker(rowsCopiedUpdateInterval)","sourceCodeStart":377,"sourceCodeEnd":413,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vttablet/tabletmanager/vreplication/vcopier.go#L377-L413","documentation":"vcopier.copyTable processes a binlog RowEvent for a table being copied, but the copy plan (built from the workflow's Filter) has no entry under plan.TargetTables for that table name. The controller only expects events for tables it planned to copy, so an unmatched table name indicates a plan/event mismatch and the copy phase fails.","triggerScenarios":"A TableMap/RowEvent arrives during the copy phase for a table not in the workflow's TargetTables — e.g. the source schema gained a new table after planning, a send-rule match is broader than the planned tables, or table name casing differs.","commonSituations":"A table is created on the source mid-copy; filter send-rule wildcards (e.g. 't.*') match more tables than the plan enumerated; keyspace/table name case mismatch between MySQL and Vitess.","solutions":["Check the workflow's TargetTables in the plan log and confirm the offending table should be copied","Update the workflow Filter send-rules to explicitly include or exclude the table, then restart the copy phase","If the table was created mid-copy, recreate the workflow so the plan includes it","Verify consistent table name casing between source MySQL and the filter rules"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Confirm the table is covered by the workflow filter before copy\n-- compare source table list against the workflow's TargetTables / send-rules","typeGuard":null,"tryCatchPattern":"if err := vc.copyNext(ctx); err != nil {\n  if strings.Contains(err.Error(), \"plan not found for table\") {\n    // table appeared mid-copy or filter mismatch: rebuild workflow\n    // reload the plan / recreate the workflow with corrected rules\n  }\n  return err\n}","preventionTips":["Create tables on the source before or after the copy phase, not during","Use precise send-rule matches rather than broad wildcards","Keep table name casing consistent between MySQL and filter rules","Recreate the workflow after schema changes on copied tables"],"tags":["vreplication","vcopier","copy-phase","plan-mismatch"],"backgroundTag":"copy-plan-table-not-found","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}