oraios/serena · error · ValueError

Invalid nixd configuration file '{config_path}': expected a

Error message

Invalid nixd configuration file '{config_path}': expected a JSON object containing the value of the 'nixd' section

What it means

This ValueError is raised when the nixd configuration file parses as valid JSON but its top level is not a JSON object (dict). The library expects the file to contain either a full settings object or the value of the 'nixd' section directly, so an array, string, number, or boolean at the top level is rejected. It is thrown from _load_nixd_settings during server startup.

Source

Thrown at src/solidlsp/language_servers/nixd_ls.py:266

        if not isinstance(config_path_value, str) or not config_path_value.strip():
            raise ValueError("ls_specific_settings.nix.config_path must be a non-empty absolute path")

        config_path = Path(config_path_value).expanduser()
        if not config_path.is_absolute():
            raise ValueError(f"ls_specific_settings.nix.config_path must be absolute: {config_path_value!r}")

        try:
            with config_path.open(encoding="utf-8") as config_file:
                settings = json.load(config_file)
        except json.JSONDecodeError as exc:
            raise ValueError(
                f"Invalid JSON in nixd configuration file '{config_path}': {exc.msg} (line {exc.lineno}, column {exc.colno})"
            ) from exc
        except OSError as exc:
            raise RuntimeError(f"Failed to read nixd configuration file '{config_path}': {exc}") from exc

        if not isinstance(settings, dict):
            raise ValueError(
                f"Invalid nixd configuration file '{config_path}': expected a JSON object containing the value of the 'nixd' section"
            )
        return settings

    @staticmethod
    def _resolve_nixd_configuration_section(settings: dict[str, Any], section: object) -> Any:
        """Resolve a ``nixd`` configuration section from the effective settings."""
        if section == "nixd":
            return deepcopy(settings)
        if not isinstance(section, str) or not section.startswith("nixd."):
            return {}

        value: Any = settings
        for key in section.removeprefix("nixd.").split("."):
            if not key or not isinstance(value, dict) or key not in value:
                return {}
            value = value[key]
        return deepcopy(value)

View on GitHub (pinned to 7fcbca7e62)

Solutions

  1. Open the config file and ensure the outermost syntax is a JSON object: { ... }.
  2. If the file currently holds a list of settings, wrap it: { "nixd": <the-list's intended structure> } or restructure options into key/value pairs.
  3. Validate the file with a JSON parser/validator (python -m json.tool <path>) and check the top-level type.
  4. If the file is meant to hold only the 'nixd' section value, that value itself must be an object; nest it accordingly.

Example fix

// before (config.json)
[
  { "nixd": { "nixpkgs": { "expr": "import <nixpkgs> {}" } } }
]
// after
{
  "nixd": { "nixpkgs": { "expr": "import <nixpkgs> {}" } }
}
Defensive patterns

Strategy: validation

Validate before calling

import json

def validate_nixd_config_is_object(path: str) -> dict:
    with open(path, "r", encoding="utf-8") as f:
        settings = json.load(f)
    if not isinstance(settings, dict):
        raise ValueError(
            f"{path}: top level must be a JSON object (the 'nixd' section value), "
            f"got {type(settings).__name__}"
        )
    return settings

Try / catch

try:
    server = NixdLanguageServer(config_path=path, **common)
except ValueError as e:
    if "expected a JSON object" in str(e):
        logger.error("nixd config %s has non-object top level: %s", path, e)
        server = NixdLanguageServer(**common)  # default settings
    else:
        raise

Prevention

When it happens

Trigger: Calling the nixd language server __init__ with a 'config_path' whose JSON file has a non-object top level, e.g. a JSON array '[...]' or a string, causing isinstance(settings, dict) to fail.

Common situations: Hand-written config that starts with '[' instead of '{'; exporting a list of options instead of an object; copy-pasting just the inner value of a key instead of the enclosing object; JSON that is a quoted string.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of oraios/serena@7fcbca7e62 (2026-08-29). Data as JSON: /api/errors/cf4678934104ba95. Report an issue: GitHub.