{"record":{"id":"68666998ab285a87","repo":"Automattic/harper","slug":"excludepatterns-must-be-an-array","errorCode":null,"errorMessage":"excludePatterns must be an array.","messagePattern":"excludePatterns must be an array\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"harper-ls/src/config.rs","lineNumber":192,"sourceCode":"                base.isolate_english = *v;\n            } else {\n                bail!(\"isolateEnglish path must be a boolean.\");\n            }\n        }\n\n        if let Some(v) = value.get(\"maxFileLength\") {\n            base.max_file_length = serde_json::from_value(v.clone())?;\n        }\n\n        if let Some(v) = value.get(\"markdown\")\n            && let Some(v) = v.get(\"IgnoreLinkTitle\")\n        {\n            base.markdown_options.ignore_link_title = serde_json::from_value(v.clone())?;\n        }\n\n        if let Some(v) = value.get(\"excludePatterns\") {\n            let Some(a) = v.as_array() else {\n                bail!(\"excludePatterns must be an array.\");\n            };\n\n            let patterns: Vec<Value> = a.to_vec();\n            if !patterns.is_empty() {\n                let mut builder = GlobSet::builder();\n\n                for pattern in patterns {\n                    builder.add(Glob::new(pattern.as_str().unwrap())?);\n                }\n\n                base.exclude_patterns = builder.build()?;\n            }\n        }\n\n        Ok(base)\n    }\n}\n","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/Automattic/harper/blob/5fe7d5ab76492d83f3ecdbc3f1da83c75dcb6f83/harper-ls/src/config.rs#L174-L210","documentation":"When `excludePatterns` is present in the LSP config, `from_lsp_config` requires it to be a JSON array of glob strings; the array is fed into a GlobSet builder used to skip documents. Non-array values (string, null, object) bail with this error before any glob compilation.","triggerScenarios":"Sending `excludePatterns` as a single string instead of an array, as null, or as an object, e.g. `{ \"excludePatterns\": \"**/node_modules/**\" }`.","commonSituations":"Users with one exclusion pattern forgetting the array brackets; config migrations from boolean/string-based settings; editors serializing a single-value setting as a scalar.","solutions":["Wrap the pattern(s) in a JSON array: [\"pattern1\", \"pattern2\"].","Remove the key if no exclusions are needed (empty arrays are accepted).","Ensure each array element is a string glob; element type errors surface later during glob compilation."],"exampleFix":"// before\n{ \"excludePatterns\": \"**/node_modules/**\" }\n// after\n{ \"excludePatterns\": [\"**/node_modules/**\"] }","handlingStrategy":"validation","validationCode":"if ('excludePatterns' in cfg) {\n  const v = cfg.excludePatterns;\n  if (!Array.isArray(v) || v.some(p => typeof p !== 'string')) {\n    throw new TypeError('excludePatterns must be an array of glob strings');\n  }\n}","typeGuard":"function isExcludePatternsOk(cfg) {\n  const v = cfg.excludePatterns;\n  return !('excludePatterns' in cfg) || (Array.isArray(v) && v.every(p => typeof p === 'string'));\n}","tryCatchPattern":null,"preventionTips":["Always wrap glob patterns in an array, even a single pattern","Ensure every element is a string","Omit the key entirely when there are no exclusions"],"tags":["lsp","config","type-mismatch","glob"],"backgroundTag":"config-type-mismatch","analyzedSha":"5fe7d5ab76492d83f3ecdbc3f1da83c75dcb6f83","analyzedAt":"2026-09-06T11:34:38.610Z","contentChangedAt":"2026-09-06T11:34:38.610Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}