{"record":{"id":"904ce6b23a30caf2","repo":"apple/pkl","slug":"maps-containing-non-string-keys-cannot-be-rendered","errorCode":null,"errorMessage":"Maps containing non-String keys cannot be rendered as JSON. Key: %s","messagePattern":"Maps containing non-String keys cannot be rendered as JSON\\. Key: (.+?)","errorType":"exception","errorClass":"RendererException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/JsonRenderer.java","lineNumber":140,"sourceCode":"        throw new UncheckedIOException(e);\n      }\n    }\n\n    @Override\n    public void visitList(List<?> value) {\n      doVisitCollection(value);\n    }\n\n    @Override\n    public void visitSet(Set<?> value) {\n      doVisitCollection(value);\n    }\n\n    @Override\n    public void visitMap(Map<?, ?> value) {\n      for (var key : value.keySet()) {\n        if (!(key instanceof String)) {\n          throw new RendererException(\n              String.format(\n                  \"Maps containing non-String keys cannot be rendered as JSON. Key: %s\", key));\n        }\n      }\n\n      @SuppressWarnings(\"unchecked\")\n      var mapValue = (Map<String, ?>) value;\n      doVisitProperties(mapValue);\n    }\n\n    @Override\n    public void visitObject(PObject value) {\n      doVisitProperties(value.getProperties());\n    }\n\n    @Override\n    public void visitModule(PModule value) {\n      doVisitProperties(value.getProperties());","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/JsonRenderer.java#L122-L158","documentation":"The Pkl JSON renderer refuses to serialize any Map whose keys are not Java Strings, because JSON object keys must be strings and the renderer does not silently coerce other key types. It pre-scans all keys in visitMap and throws a RendererException naming the offending key before writing any output.","triggerScenarios":"Calling JSON rendering (e.g. via renderer output `json` or JsonRenderer) on a Pkl mapping/object that has non-String keys, such as Int, Float, Boolean or enum keys — e.g. a `Mapping<Int>` or an object with typed non-String key properties.","commonSituations":"Converting Pkl configs with numeric lookup tables (port -> value, ID -> value) to JSON; using YAML-style integer keys that were legal in another output format; library code building Maps with typed keys and rendering them as JSON.","solutions":["Change the mapping keys to String in the Pkl source (quote them: `[\"8080\"] { ... }`)","Convert numeric/other keys to strings before rendering, e.g. iterate and build a new mapping with `key.toString()` keys","Render to a format that supports non-string keys (Pkl, YAML, or custom renderer) instead of JSON"],"exampleFix":"// before (Pkl)\nports {\n  [8080] { name = \"http\" }\n}\n// after (Pkl)\nports {\n  [\"8080\"] { name = \"http\" }\n}","handlingStrategy":"validation","validationCode":"boolean jsonSafe(Object map) {\n  return map instanceof Map<?,?> m && m.keySet().stream().allMatch(k -> k instanceof String);\n}","typeGuard":"static boolean hasStringKeys(Map<?,?> m) {\n  return m.keySet().stream().allMatch(k -> k instanceof String);\n}","tryCatchPattern":null,"preventionTips":["Use quoted string keys in Pkl mappings destined for JSON output","Coerce numeric keys to strings at config-authoring time","Audit mappings before choosing the json output format"],"tags":["json","rendering","pkl"],"backgroundTag":"json-marshal-failed","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}