{"record":{"id":"ac0d700de0f224cc","repo":"hasura/graphql-engine","slug":"failed-recursively-find-config-yaml-search-stoppe","errorCode":null,"errorMessage":"failed recursively find config.yaml: search stopped due to a possible infinite filesystem traversal at %s","messagePattern":"failed recursively find config\\.yaml: search stopped due to a possible infinite filesystem traversal at (.+?)","errorType":"exception","errorClass":"errors.Error","httpStatus":null,"severity":"error","filePath":"cli/directory.go","lineNumber":90,"sourceCode":"var filesRequired = []string{\n\t\"config.yaml\",\n}\n\n// recursivelyValidateDirectory tries to parse 'startFrom' as a project\n// directory by checking for the 'filesRequired'. If the parent of 'startFrom'\n// (nextDir) is filesystem root, error is returned. Otherwise, 'nextDir' is\n// validated, recursively.\nfunc recursivelyValidateDirectory(startFrom string) (validDir string, err error) {\n\tvar op errors.Op = \"cli.recursivelyValidateDirectory\"\n\n\terr = ValidateDirectory(startFrom)\n\tif err != nil {\n\t\tnextDir := filepath.Dir(startFrom)\n\t\t// to catch error gracefully in loop situation\n\t\tif nextDir == startFrom {\n\t\t\treturn \"\", errors.E(\n\t\t\t\top,\n\t\t\t\tfmt.Errorf(\n\t\t\t\t\t\"failed recursively find config.yaml: search stopped due to a possible infinite filesystem traversal at %s\",\n\t\t\t\t\tnextDir,\n\t\t\t\t),\n\t\t\t)\n\t\t}\n\n\t\terr := CheckFilesystemBoundary(nextDir)\n\t\tif err != nil {\n\t\t\treturn nextDir, errors.E(\n\t\t\t\top,\n\t\t\t\tfmt.Errorf(\n\t\t\t\t\t\"cannot find [%s] | search stopped: %w\",\n\t\t\t\t\tstrings.Join(filesRequired, \", \"),\n\t\t\t\t\terr,\n\t\t\t\t),\n\t\t\t)\n\t\t}\n","sourceCodeStart":72,"sourceCodeEnd":108,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/cli/directory.go#L72-L108","documentation":"recursivelyValidateDirectory walks upward from the start directory looking for the required files (config.yaml, migrations/, etc.). filepath.Dir eventually returns the same path it was given (at the filesystem root), which is used as a loop sentinel to stop the walk. Hitting it means the upward search exhausted the filesystem without finding the required files and cannot go further.","triggerScenarios":"recursivelyValidateDirectory starting from a directory whose entire ancestor chain up to / contains none of the required files, so filepath.Dir(startFrom) == startFrom at the root triggers the graceful stop.","commonSituations":"Running the CLI far away from the project root (e.g. in /tmp or $HOME) so the upward scan reaches / without finding config.yaml; a renamed or missing config.yaml breaking detection.","solutions":["cd into the project directory (the one containing config.yaml) before running the CLI","Pass the correct directory explicitly via the directory flag","Ensure config.yaml actually exists and is spelled correctly at the project root"],"exampleFix":"# before\ncd /tmp && mycli run   # upward search reaches /\n# after\ncd ~/code/myproject && mycli run","handlingStrategy":"fallback","validationCode":"if _, err := os.Stat(filepath.Join(cwd, \"config.yaml\")); err != nil {\n    // walk up ourselves with a limit, or require explicit --dir\n    log.Fatal(\"no config.yaml in cwd or ancestors; cd into the project or pass --dir\")\n}","typeGuard":null,"tryCatchPattern":"if err := ec.Validate(); err != nil {\n    if strings.Contains(err.Error(), \"infinite filesystem traversal\") {\n        // rerun from the project root or supply the directory explicitly\n    }\n}","preventionTips":["Invoke the CLI from the project root in docs and scripts","Set an explicit directory flag in automation instead of relying on discovery","Keep config.yaml at a stable, well-known project root"],"tags":["filesystem","traversal","config-discovery","go"],"backgroundTag":"config-file-not-found","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}