{"record":{"id":"8a554ebf7efe236f","repo":"Automattic/harper","slug":"ignoredlintspath-path-must-be-a-string","errorCode":null,"errorMessage":"ignoredLintsPath path must be a string.","messagePattern":"ignoredLintsPath path must be a string\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"harper-ls/src/config.rs","lineNumber":139,"sourceCode":"        if let Some(v) = value.get(\"workspaceDictPath\") {\n            if !v.is_string() {\n                bail!(\"workspaceDict path must be a string.\");\n            }\n            let path = v.as_str().unwrap();\n            if !path.is_empty() {\n                base.workspace_dict_path = path.try_resolve_in(workspace_root)?.to_path_buf();\n            }\n        } else {\n            // Resolve the default path in the project root\n            base.workspace_dict_path = base\n                .workspace_dict_path\n                .try_resolve_in(workspace_root)?\n                .to_path_buf();\n        }\n\n        if let Some(v) = value.get(\"ignoredLintsPath\") {\n            if !v.is_string() {\n                bail!(\"ignoredLintsPath path must be a string.\");\n            }\n\n            let path = v.as_str().unwrap();\n            if !path.is_empty() {\n                base.ignored_lints_path = path.try_resolve_in(workspace_root)?.to_path_buf();\n            }\n        }\n\n        if let Some(v) = value.get(\"statsPath\") {\n            if let Value::String(path) = v {\n                base.file_dict_path = path.try_resolve_in(workspace_root)?.to_path_buf();\n            } else {\n                bail!(\"fileDict path must be a string.\");\n            }\n        }\n\n        if let Some(v) = value.get(\"linters\") {\n            base.lint_config = serde_json::from_value(v.clone())?;","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/Automattic/harper/blob/5fe7d5ab76492d83f3ecdbc3f1da83c75dcb6f83/harper-ls/src/config.rs#L121-L157","documentation":"`from_lsp_config` checks that the `ignoredLintsPath` config key, when present, is a JSON string, since it is resolved (relative to the workspace root) into the file storing ignored lints. Any other JSON type triggers this bail.","triggerScenarios":"Config payload where `ignoredLintsPath` is a number, boolean, object, array, or `null` instead of a string path.","commonSituations":"Hand-edited editor settings with missing quotes, client sending `ignoredLintsPath: null` when the feature is disabled, or programmatic config generation that emits unquoted paths.","solutions":["Set `ignoredLintsPath` to a string path or remove the key.","Omit the key instead of sending null to disable it.","Re-check any script that generates the config to ensure paths are JSON-quoted strings."],"exampleFix":"// before\n{ \"ignoredLintsPath\": { \"default\": true } }\n// after\n{ \"ignoredLintsPath\": \"./ignored-lints.json\" }","handlingStrategy":"validation","validationCode":"if ('ignoredLintsPath' in cfg && typeof cfg.ignoredLintsPath !== 'string') {\n  throw new TypeError(`ignoredLintsPath must be a string, got ${typeof cfg.ignoredLintsPath}`);\n}","typeGuard":"function isIgnoredLintsPathOk(cfg) {\n  return !('ignoredLintsPath' in cfg) || typeof cfg.ignoredLintsPath === 'string';\n}","tryCatchPattern":null,"preventionTips":["Keep path settings as JSON strings","Check config-producing scripts for unquoted or typed path values","Test config changes with a minimal payload before syncing everywhere"],"tags":["lsp","config","type-mismatch","rust"],"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"}