Automattic/harper · error

ignoredLintsPath path must be a string.

Error message

ignoredLintsPath path must be a string.

What it means

`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.

Source

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

        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.");
            }

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

        if let Some(v) = value.get("statsPath") {
            if let Value::String(path) = v {
                base.file_dict_path = path.try_resolve_in(workspace_root)?.to_path_buf();
            } else {
                bail!("fileDict path must be a string.");
            }
        }

        if let Some(v) = value.get("linters") {
            base.lint_config = serde_json::from_value(v.clone())?;

View on GitHub (pinned to 5fe7d5ab76)

Solutions

  1. Set `ignoredLintsPath` to a string path or remove the key.
  2. Omit the key instead of sending null to disable it.
  3. Re-check any script that generates the config to ensure paths are JSON-quoted strings.

Example fix

// before
{ "ignoredLintsPath": { "default": true } }
// after
{ "ignoredLintsPath": "./ignored-lints.json" }
Defensive patterns

Strategy: validation

Validate before calling

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

Type guard

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

Prevention

When it happens

Trigger: Config payload where `ignoredLintsPath` is a number, boolean, object, array, or `null` instead of a string path.

Common situations: Hand-edited editor settings with missing quotes, client sending `ignoredLintsPath: null` when the feature is disabled, or programmatic config generation that emits unquoted paths.

Related errors


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