{"record":{"id":"425d28221efe6390","repo":"vitessio/vitess","slug":"invalid-joined-path","errorCode":null,"errorMessage":"invalid joined path","messagePattern":"invalid joined path","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/fileutil/join.go","lineNumber":26,"sourceCode":"    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n*/\n\npackage fileutil\n\nimport (\n\t\"errors\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"strings\"\n)\n\nvar ErrInvalidJoinedPath = errors.New(\"invalid joined path\")\n\n// SafePathJoin joins file paths using a rootPath and one or many other paths,\n// returning a single absolute path. An error is returned if the joined path\n// causes a directory traversal to a path outside of the provided rootPath.\nfunc SafePathJoin(rootPath string, joinPaths ...string) (string, error) {\n\tallPaths := make([]string, 0, len(joinPaths)+1)\n\tallPaths = append(allPaths, rootPath)\n\tallPaths = append(allPaths, joinPaths...)\n\tp := filepath.Join(allPaths...)\n\tabsPath, err := filepath.Abs(p)\n\tif err != nil {\n\t\treturn p, err\n\t}\n\tabsRootPath, err := filepath.Abs(rootPath)\n\tif err != nil {\n\t\treturn absPath, err\n\t}\n\tif absPath != absRootPath && !strings.HasPrefix(absPath, absRootPath+string(os.PathSeparator)) {","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/fileutil/join.go#L8-L44","documentation":"When choosing a random serving tablet at keyspace scope, vtadmin requires at least one tablet with State == Tablet_SERVING in the keyspace. If none exist it logs the full list of tablets searched and returns this wrapped ErrNoServingTablet error.","triggerScenarios":"Calling a keyspace-scoped RPC (e.g. GetSchema for a keyspace) where the filtered tablet list (keyspace match + SERVING state) is empty.","commonSituations":"All tablets in the keyspace are drained or down; vtadmin is pointed at the wrong cluster/cell; tablets are registered but never transitioned to serving.","solutions":["Bring up or re-enable at least one serving tablet in the keyspace","Verify tablet states via vtctldclient GetTablets and correct any non-serving tablets","Confirm vtadmin's cluster/cell discovery config points at the intended topology"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"n := 0\nfor _, t := range tablets {\n\tif t.Tablet.Keyspace == ks && t.State == vtadminpb.Tablet_SERVING { n++ }\n}\nif n == 0 { return errors.New(\"keyspace has no serving tablets\") }","typeGuard":"func hasServingTabletInKeyspace(tablets []*vtadminpb.Tablet, ks string) bool {\n\tfor _, t := range tablets {\n\t\tif t.Tablet.Keyspace == ks && t.State == vtadminpb.Tablet_SERVING {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}","tryCatchPattern":null,"preventionTips":["Verify keyspace has serving tablets before keyspace-scoped calls","Confirm vtadmin cluster/cell discovery targets the intended topology","Alert on keyspaces with zero serving tablets"],"tags":["vtadmin","tablets","serving","keyspace"],"backgroundTag":"no-serving-tablet","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}