{"record":{"id":"ada9a0ff5995462a","repo":"nikivdev/code","slug":"cycle-detected-while-loading-config-includes","errorCode":null,"errorMessage":"cycle detected while loading config includes: {}","messagePattern":"cycle detected while loading config includes: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/config.rs","lineNumber":2384,"sourceCode":"        if secrets_path.exists() {\n            if let Ok(secrets) = load_secrets(&secrets_path) {\n                merge_secrets(cfg, secrets);\n                tracing::debug!(path = %secrets_path.display(), \"loaded secrets file\");\n            }\n        }\n    }\n}\n\nfn load_with_includes(\n    path: &Path,\n    visited: &mut Vec<PathBuf>,\n    watched_paths: &mut Vec<PathBuf>,\n) -> Result<Config> {\n    let canonical = path\n        .canonicalize()\n        .with_context(|| format!(\"failed to resolve path {}\", path.display()))?;\n    if visited.contains(&canonical) {\n        anyhow::bail!(\n            \"cycle detected while loading config includes: {}\",\n            path.display()\n        );\n    }\n    visited.push(canonical.clone());\n    watched_paths.push(canonical.clone());\n\n    let contents = fs::read_to_string(&canonical)\n        .with_context(|| format!(\"failed to read flow config at {}\", path.display()))?;\n    let mut cfg: Config = match toml::from_str(&contents) {\n        Ok(cfg) => cfg,\n        Err(err) => {\n            let fix = fixup::fix_toml_content(&contents);\n            if fix.fixes_applied.is_empty() {\n                return Err(err)\n                    .with_context(|| format!(\"failed to parse flow config at {}\", path.display()));\n            }\n            let fixed = fixup::apply_fixes_to_content(&contents, &fix.fixes_applied);","sourceCodeStart":2366,"sourceCodeEnd":2402,"githubUrl":"https://github.com/nikivdev/code/blob/a747e741ae92c09071d0ae946ab48488adcff1ce/src/config.rs#L2366-L2402","documentation":"Thrown while loading a config file and its `include` chain when a file about to be loaded has already been visited in the current load (detected via canonicalized paths). This prevents infinite recursion, e.g. a config that includes itself directly or through a loop of two or more files. The message names the path where the cycle was detected.","triggerScenarios":"Config A includes config B and B includes A; a config includes itself; or two paths that canonicalize to the same file (symlink/./.. tricks) are included repeatedly.","commonSituations":"Hand-edited include chains that loop, symlinked config files (e.g. dotfile managers linking config into itself), copying a template that includes its own path, or directory+file includes resolving to the same canonical file.","solutions":["Trace the include chain printed in the message and remove the include that closes the loop","Check for symlinks: `readlink -f <path>` to see the canonical target and de-duplicate includes","Ensure each config includes at most one chain without returning to an ancestor","Restructure shared settings into a base config included once by each side"],"exampleFix":"# before (cycle)\n# config.toml\ninclude = [\"config.toml\"]\n# after\ninclude = []","handlingStrategy":"validation","validationCode":"// detect an include cycle before loading\nfn would_cycle(path: &Path, visited: &HashSet<PathBuf>) -> Result<()> {\n    let canonical = path.canonicalize()?;\n    if visited.contains(&canonical) {\n        bail!(\"config include cycle at {}\", path.display());\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"match load_config_with_includes(&path) {\n    Err(e) if e.to_string().contains(\"cycle detected while loading config includes\") => {\n        eprintln!(\"{e:#}\");\n        eprintln!(\"Fix your config: remove the include that points back to an already-loaded file (check symlinks with readlink -f).\");\n        Config::default()\n    }\n    other => other?,\n}","preventionTips":["Draw out your include graph when editing config includes by hand","Use `readlink -f` to check whether includes resolve to the same canonical file via symlinks","Keep shared settings in a single base file included once","Add a unit test that loads the shipped default config to catch cycles early"],"tags":["config","recursion","cycle"],"backgroundTag":"config-include-cycle","analyzedSha":"a747e741ae92c09071d0ae946ab48488adcff1ce","analyzedAt":"2026-09-01T22:43:55.719Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}