{"record":{"id":"98e9233f58782657","repo":"oraios/serena","slug":"gopls-settings-must-be-json-serializable-json-dum","errorCode":null,"errorMessage":"gopls_settings must be JSON-serializable (json.dumps). Use JSON-compatible values (dict/list/str/int/float/bool/null) and prefer string keys.","messagePattern":"gopls_settings must be JSON-serializable \\(json\\.dumps\\)\\. Use JSON-compatible values \\(dict/list/str/int/float/bool/null\\) and prefer string keys\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/solidlsp/language_servers/gopls.py","lineNumber":162,"sourceCode":"            # Log keys only (and at DEBUG) to avoid leaking sensitive values and to reduce startup noise.\n            log.debug(\"Applying gopls settings via initializationOptions: keys=%s\", list(gopls_settings.keys()))\n            initialize_params[\"initializationOptions\"] = gopls_settings\n\n        return initialize_params\n\n    def _validate_gopls_settings_dict(self, gopls_settings: object) -> dict:\n        if not isinstance(gopls_settings, dict):\n            raise TypeError(\n                f\"gopls_settings must be a dict, got {type(gopls_settings).__name__}. \"\n                \"Expected structure: {'buildFlags': ['-tags=foo'], 'env': {...}, ...}\"\n            )\n\n        return gopls_settings\n\n    def _canonical_json_or_raise(self, json_module: Any, data: object) -> str:\n        try:\n            return json_module.dumps(data, sort_keys=True, separators=(\",\", \":\"))\n        except (TypeError, ValueError) as exc:\n            raise TypeError(\n                \"gopls_settings must be JSON-serializable (json.dumps). Use JSON-compatible values (dict/list/str/int/float/bool/null) and prefer string keys.\"\n            ) from exc\n\n    # Environment variables that influence Go build context and affect cached symbols.\n    _CACHE_CONTEXT_ENV_KEYS = (\"GOFLAGS\", \"GOOS\", \"GOARCH\", \"CGO_ENABLED\")\n\n    @override\n    def _document_symbols_cache_fingerprint(self) -> Hashable:\n        normalize_symbol_name_version = 1\n        request_document_symbols_impl_version = 2\n        return normalize_symbol_name_version, request_document_symbols_impl_version\n\n    @override\n    def _raw_document_symbols_cache_fingerprint(self) -> Hashable:\n        gopls_settings_raw = self._custom_settings.settings.get(\"gopls_settings\")\n\n        gopls_settings: dict | None","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/oraios/serena/blob/7fcbca7e62555ec2287ddb2f083caee805848ea6/src/solidlsp/language_servers/gopls.py#L144-L180","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Convert non-JSON types before passing: set -> list, Path -> str, datetime -> ISO string","Keep dict keys as strings and values limited to dict/list/str/int/float/bool/None","If settings come from YAML, convert via json.loads(json.dumps(settings, default=str)) as a sanitizer","Inspect the exact value with json.dumps(settings) yourself to see which element fails"],"exampleFix":"// before\nsettings = {'buildFlags': {'-tags=foo'}}  # set is not JSON-serializable\n// after\nsettings = {'buildFlags': list({'-tags=foo'})}\nserver = Gopls(..., gopls_settings=settings)","handlingStrategy":"validation","validationCode":"import json\ndef ensure_json_serializable(settings) -> str:\n    try:\n        return json.dumps(settings, sort_keys=True, separators=(',', ':'))\n    except (TypeError, ValueError) as e:\n        raise TypeError(f'gopls_settings not JSON-serializable: {e}') from e","typeGuard":"import json\ndef is_json_compatible(value) -> bool:\n    try:\n        json.dumps(value)\n        return True\n    except (TypeError, ValueError):\n        return False","tryCatchPattern":"try:\n    server = Gopls(..., gopls_settings=settings)\nexcept TypeError as e:\n    if 'JSON-serializable' in str(e):\n        settings = json.loads(json.dumps(settings, default=str))  # sanitize\n        server = Gopls(..., gopls_settings=settings)","preventionTips":["Sanitize settings with default=str or explicit conversion of sets/Path/datetime","Restrict settings values to dict/list/str/int/float/bool/None","Test serialization of your settings in unit tests","Avoid Python-native types (set, Path, datetime) in config-derived settings"],"tags":["gopls","validation","json","serialization","configuration"],"backgroundTag":"non-serializable-settings-value","analyzedSha":"7fcbca7e62555ec2287ddb2f083caee805848ea6","analyzedAt":"2026-08-29T00:04:09.619Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}