Automattic/harper · error

workspaceDict path must be a string.

Error message

workspaceDict path must be a string.

What it means

Same validation pattern as fileDictPath: when `workspaceDictPath` appears in the LSP config value, `from_lsp_config` requires it to be a JSON string because it is resolved into a workspace-relative filesystem path. Non-string values abort configuration parsing.

Source

Thrown at harper-ls/src/config.rs:123

            if !path.is_empty() {
                base.user_dict_path = path.try_resolve_in(workspace_root)?.to_path_buf();
            }
        }

        if let Some(v) = value.get("fileDictPath") {
            if !v.is_string() {
                bail!("fileDict path must be a string.");
            }

            let path = v.as_str().unwrap();
            if !path.is_empty() {
                base.file_dict_path = path.try_resolve_in(workspace_root)?.to_path_buf();
            }
        }

        if let Some(v) = value.get("workspaceDictPath") {
            if !v.is_string() {
                bail!("workspaceDict path must be a string.");
            }
            let path = v.as_str().unwrap();
            if !path.is_empty() {
                base.workspace_dict_path = path.try_resolve_in(workspace_root)?.to_path_buf();
            }
        } else {
            // Resolve the default path in the project root
            base.workspace_dict_path = base
                .workspace_dict_path
                .try_resolve_in(workspace_root)?
                .to_path_buf();
        }

        if let Some(v) = value.get("ignoredLintsPath") {
            if !v.is_string() {
                bail!("ignoredLintsPath path must be a string.");
            }

View on GitHub (pinned to 5fe7d5ab76)

Solutions

  1. Change `workspaceDictPath` to a string path or delete the key to use the default.
  2. Ensure the value is not null; omit the key instead of setting it to null.
  3. Validate the settings JSON with a JSON schema/linter before sending it to the language server.

Example fix

// before
{ "workspaceDictPath": true }
// after
{ "workspaceDictPath": "./workspace-dict.txt" }
Defensive patterns

Strategy: validation

Validate before calling

if ('workspaceDictPath' in cfg && typeof cfg.workspaceDictPath !== 'string') {
  throw new TypeError(`workspaceDictPath must be a string, got ${typeof cfg.workspaceDictPath}`);
}

Type guard

function isWorkspaceDictPathOk(cfg) {
  return !('workspaceDictPath' in cfg) || typeof cfg.workspaceDictPath === 'string';
}

Prevention

When it happens

Trigger: Passing `workspaceDictPath` as a non-string in initializationOptions or DidChangeConfiguration, e.g. a boolean, number, array, or explicit `null`.

Common situations: Users hand-editing Neovim/VS Code settings and dropping quotes around a path, or migration scripts converting old boolean-toggled settings into the new path-based key with the wrong type.

Related errors


AI-assisted analysis of Automattic/harper@5fe7d5ab76 (2026-09-06). Data as JSON: /api/errors/0a1578bc01f3136b. Report an issue: GitHub.