{"record":{"id":"d3a3637b1f185292","repo":"jdx/mise","slug":"source-pattern-did-not-match-path","errorCode":null,"errorMessage":"source pattern did not match {path}","messagePattern":"source pattern did not match (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/files.rs","lineNumber":1169,"sourceCode":"                policy,\n                variants: vec![],\n                enabled,\n            })\n        })\n        .collect()\n}\n\nfn is_glob_pattern(path: &Path) -> bool {\n    path.to_string_lossy()\n        .chars()\n        .any(|c| matches!(c, '*' | '?' | '['))\n}\n\nfn wildcard_captures(pattern: &str, path: &Path) -> Result<Vec<String>> {\n    let path = normalize_path_separators(&path.to_string_lossy());\n    let re = wildcard_regex(pattern)?;\n    let Some(captures) = re.captures(&path) else {\n        bail!(\"source pattern did not match {path}\");\n    };\n    Ok((1..captures.len())\n        .map(|i| {\n            captures\n                .get(i)\n                .map(|m| m.as_str().to_string())\n                .unwrap_or_default()\n        })\n        .collect())\n}\n\nfn wildcard_regex(pattern: &str) -> Result<Regex> {\n    let mut re = String::from(\"^\");\n    let pattern = normalize_path_separators(pattern);\n    let mut chars = pattern.chars().peekable();\n    while let Some(ch) = chars.next() {\n        match ch {\n            '*' if chars.peek() == Some(&'*') => {","sourceCodeStart":1151,"sourceCodeEnd":1187,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/system/files.rs#L1151-L1187","documentation":"Wildcards in a dotfile source pattern (`*`, `?`, `[...]`) are compiled to a regex and matched against the discovered path to capture directory segments used to build the expanded target. If a candidate path does not match the pattern at all, `wildcard_captures` cannot derive target components and errors instead of producing a malformed expansion.","triggerScenarios":"Calling the wildcard expansion path (e.g. via `expand_request`) with a path whose normalized form is not matched by the source pattern's regex — typically a path from a different depth or directory shape than the pattern expects.","commonSituations":"Changing a source pattern (e.g. from `configs/*.conf` to `configs/**/*.conf`) so previously matching files no longer match; symlinks or `..` segments altering the normalized path; running expansion on a stale cached path after the dotfiles root moved.","solutions":["Check the pattern in the message against the actual path printed; adjust the wildcards (add `**/` for arbitrary depth, `?` for single chars) so the path matches.","Ensure the source file actually lives under the dotfiles root at the location the pattern describes.","Re-run dotfiles apply/status so discovery re-runs against the current tree (clears stale paths).","If you wrote a custom regex-like pattern, verify its syntax matches the tool's wildcard dialect (`wildcard_regex`)."],"exampleFix":"// before: pattern configs/*.conf cannot match nested file\nsource = \"configs/*.conf\"  # found configs/editors/vim.conf\n\n// after\nsource = \"configs/**/*.conf\"","handlingStrategy":"try-catch","validationCode":"// pre-check a pattern against sample paths using the same wildcard dialect\nfunction patternMatches(pattern, path) {\n  const re = new RegExp('^' + pattern.replace(/\\*\\*/g, '.*').replace(/\\*/g, '[^/]*').replace(/\\?/g, '.') + '$');\n  return re.test(path);\n}","typeGuard":null,"tryCatchPattern":"try {\n  expandWildcards();\n} catch (e) {\n  if (/source pattern did not match/.test(e.message)) {\n    const path = e.message.split('did not match ')[1];\n    console.error(`Adjust the wildcard pattern so it matches ${path} (check depth and separators)`);\n  } else throw e;\n}","preventionTips":["Test wildcard patterns against both shallow and nested layouts when restructuring the dotfiles repo","Prefer `**/` when files may appear at varying depths","Keep source tree depth in sync with the patterns documented in your dotfiles README"],"tags":["dotfiles","wildcard","glob-matching","mise"],"backgroundTag":"pattern-match-failed","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}