{"record":{"id":"f456b3bd90308919","repo":"apache/beam","slug":"failed-to-convert-pipelineoptions-to-protocol","errorCode":null,"errorMessage":"Failed to convert PipelineOptions to Protocol","messagePattern":"Failed to convert PipelineOptions to Protocol","errorType":"exception","errorClass":"java.lang.RuntimeException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/PipelineOptionsTranslation.java","lineNumber":82,"sourceCode":"            \"Unable to convert pipeline options, please check for outdated jackson-core version in the classpath.\");\n      }\n\n      Map<String, TreeNode> optionsUsingUrns = new HashMap<>();\n      while (optionsEntries.hasNext()) {\n        Map.Entry<String, JsonNode> entry = optionsEntries.next();\n        optionsUsingUrns.put(\n            PIPELINE_OPTIONS_URN_PREFIX\n                + CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, entry.getKey())\n                + PIPELINE_OPTIONS_URN_SUFFIX,\n            entry.getValue());\n      }\n\n      // The JSON format of a Protobuf Struct is the JSON object that is equivalent to that struct\n      // (with values encoded in a standard json-codeable manner). See Beam PR 3719 for more.\n      JsonFormat.parser().merge(MAPPER.writeValueAsString(optionsUsingUrns), builder);\n      return builder.build();\n    } catch (IOException e) {\n      throw new RuntimeException(\"Failed to convert PipelineOptions to Protocol\", e);\n    }\n  }\n\n  /** Converts the provided {@link Struct} into {@link PipelineOptions}. */\n  public static PipelineOptions fromProto(Struct protoOptions) {\n    try {\n      Map<String, TreeNode> mapWithoutUrns = new HashMap<>();\n      TreeNode rootOptions = MAPPER.readTree(JsonFormat.printer().print(protoOptions));\n      Iterator<String> optionsKeys = rootOptions.fieldNames();\n      while (optionsKeys.hasNext()) {\n        String optionKey = optionsKeys.next();\n        TreeNode optionValue = rootOptions.get(optionKey);\n        mapWithoutUrns.put(\n            CaseFormat.LOWER_UNDERSCORE.to(\n                CaseFormat.LOWER_CAMEL,\n                optionKey.substring(\n                    PIPELINE_OPTIONS_URN_PREFIX.length(),\n                    optionKey.length() - PIPELINE_OPTIONS_URN_SUFFIX.length())),","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/PipelineOptionsTranslation.java#L64-L100","documentation":"After converting each pipeline option to a TreeNode keyed by URN, toProto merges the Jackson JSON into a protobuf Struct via JsonFormat.parser().merge(...). If any step throws IOException (typically Jackson serialization failure of the options map), it is wrapped in a RuntimeException with this message.","triggerScenarios":"Calling PipelineOptionsTranslation.toProto/toJson when MAPPER.writeValueAsString(optionsUsingUrns) throws IOException — e.g. an option value whose Jackson serialization fails (unserializable object, broken custom serializer).","commonSituations":"Custom PipelineOptions with getters returning objects Jackson cannot serialize; broken JsonSerialize annotations on option types; Jackson version mismatches at runtime.","solutions":["Read the wrapped IOException cause to find which option value failed to serialize","Make the offending PipelineOptions property return a Jackson-friendly type (String, primitives, POJOs)","Annotate non-serializable option properties with @JsonIgnore and expose a serializable representation"],"exampleFix":"// before\nMyConfig getConfig(); // unserializable third-party type\n// after\n@JsonIgnore MyConfig getConfig();\n@JsonProperty String getConfigJson() { return serialize(getConfig()); }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { Struct s = PipelineOptionsTranslation.toProto(options); } catch (RuntimeException e) { throw new IllegalStateException(\"PipelineOptions serialization failed: \" + e.getCause(), e); }","preventionTips":["Keep PipelineOptions getters Jackson-serializable","Annotate non-serializable properties with @JsonIgnore","Test toProto/toJson round-trips for custom options"],"tags":["java","apache-beam","pipeline-options","jackson","serialization"],"backgroundTag":"json-marshal-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}