{"record":{"id":"3a509eefb14dc29d","repo":"vitessio/vitess","slug":"cannot-get-vtroot-v","errorCode":null,"errorMessage":"cannot get VTROOT: %v","messagePattern":"cannot get VTROOT: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/hook/hook.go","lineNumber":105,"sourceCode":"\treturn &Hook{Name: name, Parameters: params}\n}\n\n// NewSimpleHook returns a Hook object with just a name.\nfunc NewSimpleHook(name string) *Hook {\n\treturn &Hook{Name: name}\n}\n\n// NewHookWithEnv returns a Hook object with the provided name, params and ExtraEnv.\nfunc NewHookWithEnv(name string, params []string, env map[string]string) *Hook {\n\treturn &Hook{Name: name, Parameters: params, ExtraEnv: env}\n}\n\n// findHook tries to locate the hook, and returns the exec.Cmd for it.\nfunc (hook *Hook) findHook(ctx context.Context) (*exec.Cmd, int, error) {\n\t// Find our root.\n\troot, err := vtenv.VtRoot()\n\tif err != nil {\n\t\treturn nil, HOOK_VTROOT_ERROR, fmt.Errorf(\"cannot get VTROOT: %v\", err)\n\t}\n\n\t// See if the hook exists.\n\tvthook, err := fileutil.SafePathJoin(filepath.Join(root, \"vthook\"), hook.Name)\n\tif err != nil {\n\t\treturn nil, HOOK_INVALID_NAME, fmt.Errorf(\"invalid hook name %q: %v\", hook.Name, err)\n\t}\n\t_, err = os.Stat(vthook)\n\tif err != nil {\n\t\tif os.IsNotExist(err) {\n\t\t\treturn nil, HOOK_DOES_NOT_EXIST, fmt.Errorf(\"missing hook %v\", vthook)\n\t\t}\n\n\t\treturn nil, HOOK_STAT_FAILED, fmt.Errorf(\"cannot stat hook %v: %v\", vthook, err)\n\t}\n\n\t// Configure the command.\n\tlog.Info(fmt.Sprintf(\"hook: executing hook: %v %v\", vthook, strings.Join(hook.Parameters, \" \")))","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/hook/hook.go#L87-L123","documentation":"Hook.Lookup resolves the VTROOT environment directory to find where vthook binaries live. When vtenv.VtRoot() cannot determine the Vitess root directory, findHook returns HOOK_VTROOT_ERROR with this message. It means the hook could not even be located because the installation root is unknown, not that a specific hook is missing.","triggerScenarios":"Calling hook.ExecuteContext / ExecuteAsWritePipe / ExecuteAsReadPipe (via findHook) in a process where the VTROOT-resolving logic fails — vtenv.VtRoot() returns an error because no Vitess root is configured/discoverable.","commonSituations":"Running Vitess binaries outside a standard deployment layout; VTROOT env var unset and binary not run from within a Vitess distribution; container images missing the vtenv-discoverable root.","solutions":["Set the VTROOT environment variable to the Vitess installation root before starting the process","Run the binary from within a proper Vitess distribution so vtenv can discover the root automatically","Check the wrapped error (%v) from vtenv.VtRoot() for the specific reason the root lookup failed"],"exampleFix":"// before: hook.ExecuteContext(...) fails with 'cannot get VTROOT'\n// after (in deployment env)\nexport VTROOT=/usr/local/vitess\n// or in Go tests\nos.Setenv(\"VTROOT\", \"/usr/local/vitess\")","handlingStrategy":"validation","validationCode":"if os.Getenv(\"VTROOT\") == \"\" {\n    if _, err := vtenv.VtRoot(); err != nil {\n        return fmt.Errorf(\"hooks unavailable: VTROOT not resolvable: %v\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"hr := hook.ExecuteOptional(h)\nif hr.ExitStatus == hook.HOOK_VTROOT_ERROR {\n    log.Warningf(\"hooks disabled: VTROOT not set\")\n    return nil\n}","preventionTips":["Always set VTROOT in deployment environments and container images","Check exit status HOOK_VTROOT_ERROR to degrade gracefully when hooks are unavailable","Verify the Vitess distribution layout (vthook dir under root) before enabling hooks"],"tags":["environment","hook","configuration"],"backgroundTag":"missing-env-var","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}