oraios/serena · error · TypeError

gopls_settings must be JSON-serializable (json.dumps). Use J

Error message

gopls_settings must be JSON-serializable (json.dumps). Use JSON-compatible values (dict/list/str/int/float/bool/null) and prefer string keys.

What it means

TypeError raised by Gopls._canonical_json_or_raise when gopls_settings cannot be serialized with json.dumps (sort_keys=True). The settings are embedded in LSP initializationOptions and in a canonical cache fingerprint, so they must contain only JSON-compatible values. Values like sets, datetime, bytes, or non-string dict keys cause this.

Source

Thrown at src/solidlsp/language_servers/gopls.py:162

            # Log keys only (and at DEBUG) to avoid leaking sensitive values and to reduce startup noise.
            log.debug("Applying gopls settings via initializationOptions: keys=%s", list(gopls_settings.keys()))
            initialize_params["initializationOptions"] = gopls_settings

        return initialize_params

    def _validate_gopls_settings_dict(self, gopls_settings: object) -> dict:
        if not isinstance(gopls_settings, dict):
            raise TypeError(
                f"gopls_settings must be a dict, got {type(gopls_settings).__name__}. "
                "Expected structure: {'buildFlags': ['-tags=foo'], 'env': {...}, ...}"
            )

        return gopls_settings

    def _canonical_json_or_raise(self, json_module: Any, data: object) -> str:
        try:
            return json_module.dumps(data, sort_keys=True, separators=(",", ":"))
        except (TypeError, ValueError) as exc:
            raise TypeError(
                "gopls_settings must be JSON-serializable (json.dumps). Use JSON-compatible values (dict/list/str/int/float/bool/null) and prefer string keys."
            ) from exc

    # Environment variables that influence Go build context and affect cached symbols.
    _CACHE_CONTEXT_ENV_KEYS = ("GOFLAGS", "GOOS", "GOARCH", "CGO_ENABLED")

    @override
    def _document_symbols_cache_fingerprint(self) -> Hashable:
        normalize_symbol_name_version = 1
        request_document_symbols_impl_version = 2
        return normalize_symbol_name_version, request_document_symbols_impl_version

    @override
    def _raw_document_symbols_cache_fingerprint(self) -> Hashable:
        gopls_settings_raw = self._custom_settings.settings.get("gopls_settings")

        gopls_settings: dict | None

View on GitHub (pinned to 7fcbca7e62)

Solutions

  1. Convert non-JSON types before passing: set -> list, Path -> str, datetime -> ISO string
  2. Keep dict keys as strings and values limited to dict/list/str/int/float/bool/None
  3. If settings come from YAML, convert via json.loads(json.dumps(settings, default=str)) as a sanitizer
  4. Inspect the exact value with json.dumps(settings) yourself to see which element fails

Example fix

// before
settings = {'buildFlags': {'-tags=foo'}}  # set is not JSON-serializable
// after
settings = {'buildFlags': list({'-tags=foo'})}
server = Gopls(..., gopls_settings=settings)
Defensive patterns

Strategy: validation

Validate before calling

import json
def ensure_json_serializable(settings) -> str:
    try:
        return json.dumps(settings, sort_keys=True, separators=(',', ':'))
    except (TypeError, ValueError) as e:
        raise TypeError(f'gopls_settings not JSON-serializable: {e}') from e

Type guard

import json
def is_json_compatible(value) -> bool:
    try:
        json.dumps(value)
        return True
    except (TypeError, ValueError):
        return False

Try / catch

try:
    server = Gopls(..., gopls_settings=settings)
except TypeError as e:
    if 'JSON-serializable' in str(e):
        settings = json.loads(json.dumps(settings, default=str))  # sanitize
        server = Gopls(..., gopls_settings=settings)

Prevention

When it happens

Trigger: Passing gopls_settings containing non-JSON values — e.g. Python sets, datetime objects, Path objects, tuples-as-keys, or circular references — into Gopls initialization or the document-symbols cache fingerprint computation.

Common situations: Building settings programmatically with Python-native types (set(), Path, datetime); YAML config that parsed a value into a non-JSON type; non-string dict keys mixed with string keys.

Related errors


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