{"record":{"id":"b22662c2148bba7e","repo":"Automattic/harper","slug":"filedict-path-must-be-a-string","errorCode":null,"errorMessage":"fileDict path must be a string.","messagePattern":"fileDict path must be a string\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"harper-ls/src/config.rs","lineNumber":112,"sourceCode":"\n        let Some(Value::Object(value)) = value.get(\"harper-ls\") else {\n            bail!(\"Settings must contain a \\\"harper-ls\\\" key.\");\n        };\n\n        if let Some(v) = value.get(\"userDictPath\") {\n            if !v.is_string() {\n                bail!(\"userDict path must be a string.\");\n            }\n\n            let path = v.as_str().unwrap();\n            if !path.is_empty() {\n                base.user_dict_path = path.try_resolve_in(workspace_root)?.to_path_buf();\n            }\n        }\n\n        if let Some(v) = value.get(\"fileDictPath\") {\n            if !v.is_string() {\n                bail!(\"fileDict path must be a string.\");\n            }\n\n            let path = v.as_str().unwrap();\n            if !path.is_empty() {\n                base.file_dict_path = path.try_resolve_in(workspace_root)?.to_path_buf();\n            }\n        }\n\n        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","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/Automattic/harper/blob/5fe7d5ab76492d83f3ecdbc3f1da83c75dcb6f83/harper-ls/src/config.rs#L94-L130","documentation":"harper-ls validates the `fileDictPath` field of the LSP initialization/configuration value. If the key is present but its value is not a JSON string (e.g. number, object, boolean), `from_lsp_config` bails with this error instead of proceeding. The check exists because the value is later resolved as a filesystem path.","triggerScenarios":"Sending a DidChangeConfiguration or initializationOptions payload in which `fileDictPath` is set to a non-string value, e.g. `\"fileDictPath\": 123`, `true`, `null` inside an object, or a nested config object.","commonSituations":"Editor settings JSON where a user typed an unquoted path-like number, a settings-sync tool serialized the value as a number/boolean, or a client passed the default `null` inside the config object rather than omitting the key.","solutions":["Set `fileDictPath` to a string value (e.g. \"./file-dict.txt\") or remove the key entirely.","Check for `null` sent by the client; some editors serialize disabled settings as null — omit the key instead.","Fix quoting in the settings JSON so the path is a proper JSON string."],"exampleFix":"// before (LSP config JSON)\n{ \"harper-ls\": { \"fileDictPath\": 42 } }\n// after\n{ \"harper-ls\": { \"fileDictPath\": \"./file-dict.txt\" } }","handlingStrategy":"validation","validationCode":"const cfg = settings['harper-ls'] ?? {};\nif ('fileDictPath' in cfg && typeof cfg.fileDictPath !== 'string') {\n  throw new TypeError(`fileDictPath must be a string, got ${typeof cfg.fileDictPath}`);\n}","typeGuard":"function isFileDictPathOk(cfg) {\n  return !('fileDictPath' in cfg) || typeof cfg.fileDictPath === 'string';\n}","tryCatchPattern":null,"preventionTips":["Omit config keys instead of sending null for unset options","Run settings JSON through a schema validator before applying","Quote all path values in hand-edited settings files"],"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-14T05:17:10.506Z"}