{"record":{"id":"f44d6888b0418ff7","repo":"apple/pkl","slug":"values-of-type-duration-cannot-be-rendered-as-js","errorCode":null,"errorMessage":"Values of type `Duration` cannot be rendered as JSON. Value: %s","messagePattern":"Values of type `Duration` cannot be rendered as JSON\\. Value: (.+?)","errorType":"exception","errorClass":"RendererException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/JsonRenderer.java","lineNumber":95,"sourceCode":"      try {\n        writer.value(value);\n      } catch (IOException e) {\n        throw new UncheckedIOException(e);\n      }\n    }\n\n    @Override\n    public void visitBoolean(Boolean value) {\n      try {\n        writer.value(value);\n      } catch (IOException e) {\n        throw new UncheckedIOException(e);\n      }\n    }\n\n    @Override\n    public void visitDuration(Duration value) {\n      throw new RendererException(\n          String.format(\"Values of type `Duration` cannot be rendered as JSON. Value: %s\", value));\n    }\n\n    @Override\n    public void visitDataSize(DataSize value) {\n      throw new RendererException(\n          String.format(\"Values of type `DataSize` cannot be rendered as JSON. Value: %s\", value));\n    }\n\n    @Override\n    public void visitBytes(byte[] value) {\n      throw new RendererException(\n          String.format(\n              \"Values of type `Bytes` cannot be rendered as JSON. Value: %s\", (Object) value));\n    }\n\n    // Pair coming from the runtime can never admit null (in-language null is represented as PNull)\n    @SuppressWarnings(\"DataFlowIssue\")","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/JsonRenderer.java#L77-L113","documentation":"JsonRenderer throws this RendererException whenever it is asked to render a Pkl Duration value as JSON, because the JSON output format has no representation for durations. It is a deliberate hard stop rather than a silent coercion.","triggerScenarios":"Rendering a Pkl module/property tree to JSON while a property evaluates to a Duration (e.g. `x = 5.min`), via any code path that dispatches visitDuration on the renderer.","commonSituations":"JSON-rendering an API or config module that contains duration-typed fields such as timeouts, intervals, or TTLs.","solutions":["Convert the Duration to a number or string before rendering (e.g. value.value in seconds or value.isoString())","Restructure the module so duration fields are excluded or represented as Int/Float/String","Use a renderer/format that supports durations if JSON is not required"],"exampleFix":"// before\nprop timeout: Duration = 5.min\n// after\nprop timeoutSeconds: Number = 5.min.value // 300","handlingStrategy":"type-guard","validationCode":"// before rendering, walk values and reject unsupported types\nif (value instanceof Duration) {\n  throw new IllegalArgumentException(\"convert Duration before JSON rendering\");\n}","typeGuard":"boolean isJsonRenderable(Object v) {\n  return !(v instanceof Duration || v instanceof DataSize || v instanceof byte[]);\n}","tryCatchPattern":"try {\n  renderer.render(value);\n} catch (RendererException e) {\n  // value type unsupported by JSON renderer; convert or exclude it\n  LOG.error(\"JSON rendering unsupported: {}\", e.getMessage());\n}","preventionTips":["Audit modules for Duration/DataSize/Bytes properties before choosing JSON output","Expose numeric/string projections (e.g. .value, .isoString()) for such properties","Catch RendererException at the render boundary and fall back to Pkl/other formats"],"tags":["java","pkl","json","renderer"],"backgroundTag":"json-serialization-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"}