{"record":{"id":"da98ad0240a09801","repo":"apple/pkl","slug":"invalidprotobuftoplevelvalue","errorCode":"invalidProtobufTopLevelValue","errorMessage":"invalidProtobufTopLevelValue","messagePattern":"invalidProtobufTopLevelValue","errorType":"error_code","errorClass":"VmException","httpStatus":null,"severity":"error","filePath":"pkl-core/src/main/java/org/pkl/core/stdlib/protobuf/RendererNodes.java","lineNumber":167,"sourceCode":"\n    public ProtobufRenderer(StringBuilder builder, String indent, PklConverter converter) {\n      super(\"Protobuf\", builder, indent, converter, true, true);\n    }\n\n    @Override\n    protected void visitDocument(Object value) {\n      visit(value);\n      startNewLine();\n    }\n\n    @Override\n    protected void visitTopLevelValue(Object value) {\n      if (value instanceof VmValue && !(value instanceof VmTyped || value instanceof VmDuration)) {\n        var name = value.getClass().getSimpleName();\n        if (name.startsWith(\"Vm\")) {\n          name = name.substring(2);\n        }\n        throw new VmExceptionBuilder().evalError(\"invalidProtobufTopLevelValue\", name).build();\n      }\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) {","sourceCodeStart":149,"sourceCodeEnd":185,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-core/src/main/java/org/pkl/core/stdlib/protobuf/RendererNodes.java#L149-L185","documentation":"The Protobuf renderer rejects top-level values that are internal Pkl value kinds (VmValue subclasses) other than Typed objects and Duration. Values like IntSeq, Pair, Regex, etc. have no protobuf mapping at the document root, and the error reports the stripped Vm-prefixed class name.","triggerScenarios":"Calling protobuf rendering with a top-level value such as an IntSeq, Pair, Listing-internal value, Regex, or other non-Typed/non-Duration VmValue.","commonSituations":"Pointing a protobuf output at `output.value` that holds a Pkl collection or utility value instead of a typed object; migrating a renderer from JSON (permissive) to protobuf (restrictive).","solutions":["Render a typed object (module/class instance) as the top-level value","Convert primitives/Duration-like values appropriately (Duration is allowed; e.g. wrap others in a typed object)","Switch to JSON/Pcf/YAML renderer for non-object top-level values"],"exampleFix":"// before\noutput.value = Pair(1, 2)\noutput.renderer = new ProtobufRenderer\n// after\noutput.value = new { pair = new Dynamic { first = 1; second = 2 } }\noutput.renderer = new ProtobufRenderer","handlingStrategy":"validation","validationCode":"function isProtobufTopLevel(v) { return isPklTyped(v) || isDuration(v); }","typeGuard":"const isProtobufTopLevelOk = (v) => isPklTyped(v) || isPklDuration(v);","tryCatchPattern":"try { renderAsProtobuf(value) } catch (e) { if (e.code === 'invalidProtobufTopLevelValue') { /* wrap in typed object */ } else throw e }","preventionTips":["Use typed objects (or Duration) as protobuf top-level values","Never render Pair/IntSeq/Regex etc. directly to protobuf","When migrating renderers, re-check top-level value type per format"],"tags":["pkl","protobuf","renderer","top-level-value"],"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"}