{"record":{"id":"7658e28837ae8572","repo":"apple/pkl","slug":"cannotrendertypeaddconverter","errorCode":"cannotRenderTypeAddConverter","errorMessage":"cannotRenderTypeAddConverter","messagePattern":"cannotRenderTypeAddConverter","errorType":"error_code","errorClass":"VmException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/stdlib/protobuf/RendererNodes.java","lineNumber":186,"sourceCode":"      }\n      assert propertyPath.isEmpty() && wrapperRequirement.isEmpty() : \"Corrupted traversal stack.\";\n      wrapperRequirement.push(false);\n      visit(value);\n      var wrap = wrapperRequirement.pop();\n      assert !wrap && propertyPath.isEmpty() && wrapperRequirement.isEmpty()\n          : \"Corrupted traversal stack.\";\n    }\n\n    @Override\n    protected void visitRenderDirective(VmTyped value) {\n      writePropertyName();\n      // append verbatim\n      builder.append(VmUtils.readTextProperty(value));\n    }\n\n    @Override\n    protected void startDynamic(VmDynamic value) {\n      throw new VmExceptionBuilder()\n          .evalError(\"cannotRenderTypeAddConverter\", \"Dynamic\", \"Protobuf\")\n          .withProgramValue(\"Value\", value)\n          .build();\n    }\n\n    @Override\n    protected void endDynamic(VmDynamic value, boolean isEmpty) {}\n\n    @Override\n    protected void startTyped(VmTyped value) {\n      wrapperRequirement.push(false);\n      if (!propertyPath.isEmpty()) {\n        writePropertyName();\n        startMessage();\n      }\n    }\n\n    @Override","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/stdlib/protobuf/RendererNodes.java#L168-L204","documentation":"Protobuf rendering does not support `Dynamic` objects because protobuf requires a known schema/type; the renderer tells you to add a converter instead of guessing. Thrown when traversal reaches a VmDynamic node.","triggerScenarios":"Rendering a value to protobuf where a `Dynamic` object appears (as the top-level value or nested property) and no custom converter handles that type.","commonSituations":"Using `new Dynamic { ... }` or `dynamic { ... }` values inside a module rendered to protobuf; prototyping with Dynamic values then switching output format to protobuf without converting to typed classes.","solutions":["Convert the Dynamic value into a typed Pkl class so the renderer can map it to a protobuf message","Register/add a custom converter for the type in the ProtobufRenderer configuration","Replace Dynamic usage with defined classes in the module being rendered"],"exampleFix":"// before\noutput.value = new Dynamic { name = \"x\" }\noutput.renderer = new ProtobufRenderer\n// after\nclass Person { name: String }\noutput.value = (Person) { name = \"x\" }\noutput.renderer = new ProtobufRenderer","handlingStrategy":"fallback","validationCode":"function hasNoDynamic(v) { return !containsKind(v, 'Dynamic'); }","typeGuard":"const isTypedNotDynamic = (v) => isPklTyped(v) && !isPklDynamic(v);","tryCatchPattern":"try { renderAsProtobuf(value) } catch (e) { if (e.code === 'cannotRenderTypeAddConverter') { /* fall back to JSON or add converter */ } else throw e }","preventionTips":["Replace Dynamic values with typed classes in protobuf-rendered modules","Configure converters for any third-party Dynamic values","Keep Dynamic usage confined to prototyping, not protobuf output paths"],"tags":["pkl","protobuf","renderer","dynamic"],"backgroundTag":"unsupported-operation","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"}