{"record":{"id":"9280844c01dcbb3c","repo":"vitessio/vitess","slug":"w-d-schemas-found-with-table-named-s","errorCode":null,"errorMessage":"%w: %d schemas found with table named %s","messagePattern":"%w: (.+?) schemas found with table named (.+?)","errorType":"exception","errorClass":"ErrAmbiguousSchema","httpStatus":null,"severity":"warning","filePath":"go/vt/vtadmin/api.go","lineNumber":788,"sourceCode":"\t\t}(c)\n\t}\n\n\twg.Wait()\n\n\tif rec.HasErrors() {\n\t\treturn nil, rec.Error()\n\t}\n\n\tswitch len(results) {\n\tcase 0:\n\t\treturn nil, &errors.NoSuchSchema{\n\t\t\tClusters: clusterIDs,\n\t\t\tTable:    req.Table,\n\t\t}\n\tcase 1:\n\t\treturn results[0], nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"%w: %d schemas found with table named %s\", errors.ErrAmbiguousSchema, len(results), req.Table)\n\t}\n}\n\n// GetBackups is part of the vtadminpb.VTAdminServer interface.\nfunc (api *API) GetBackups(ctx context.Context, req *vtadminpb.GetBackupsRequest) (*vtadminpb.GetBackupsResponse, error) {\n\tspan, ctx := trace.NewSpan(ctx, \"API.GetBackups\")\n\tdefer span.Finish()\n\n\tclusters, _ := api.getClustersForRequest(req.ClusterIds)\n\n\tvar (\n\t\tm       sync.Mutex\n\t\twg      sync.WaitGroup\n\t\trec     concurrency.AllErrorRecorder\n\t\tbackups []*vtadminpb.ClusterBackup\n\t)\n\n\tif req.RequestOptions == nil {","sourceCodeStart":770,"sourceCodeEnd":806,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtadmin/api.go#L770-L806","documentation":"VTAdmin's FindSchema RPC searches all clusters for schemas containing the requested table; when the table is found in more than one distinct schema it refuses to guess and returns errors.ErrAmbiguousSchema wrapped with the match count and table name. This protects callers from silently acting on the wrong keyspace/table definition. Exactly one match returns that schema; zero matches are handled earlier in the switch.","triggerScenarios":"Calling FindSchema (GET /schema?table=users) where the table name exists in schemas of 2+ clusters (per the request's cluster filter) so the default case (len(results) > 1) is hit.","commonSituations":"Multi-cluster setups where the same table name (e.g. 'users') is deployed in several keyspaces/clusters; calling without narrowing Clusters in the request; shared table naming conventions across environments.","solutions":["Narrow the request to a single cluster by setting Clusters in the FindSchema request (or the cluster_ids query param)","Use a more specific table name, including keyspace qualification if the API path supports it","If the ambiguity is a real duplicate, pick the intended cluster and query its schema directly via GetSchema"],"exampleFix":"// before\nGET /api/schema?table=users\n// after\nGET /api/schema?table=users&cluster_ids=commerce","handlingStrategy":"try-catch","validationCode":"const matches = await Promise.all(clusterIds.map(c => getSchema(c, table).catch(() => null)));\nconst found = matches.filter(Boolean);\nif (found.length > 1) {\n  throw new Error('table ' + table + ' exists in ' + found.length + ' clusters; narrow with cluster_ids');\n}","typeGuard":"function isAmbiguousSchema(err: unknown): boolean {\n  return err instanceof Error && err.message.includes('schemas found with table named');\n}","tryCatchPattern":"try {\n  schema = await findSchema(table, clusterIds);\n} catch (err) {\n  if (isAmbiguousSchema(err)) {\n    const n = parseInt(err.message, 10);\n    schema = await findSchema(table, [preferredCluster]);\n  } else {\n    throw err;\n  }\n}","preventionTips":["Always pass cluster_ids to FindSchema in multi-cluster deployments","Avoid relying on table-name uniqueness across clusters; qualify with cluster or keyspace","Adopt distinct naming conventions for environment-specific tables"],"tags":["vtadmin","schema","ambiguity","multi-cluster"],"backgroundTag":"ambiguous-schema-match","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}