{"record":{"id":"6fbe71fad95601fe","repo":"apache/beam","slug":"failed-to-read-pipelineoptions-from-protocol","errorCode":null,"errorMessage":"Failed to read PipelineOptions from Protocol","messagePattern":"Failed to read PipelineOptions from 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":107,"sourceCode":"      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())),\n            optionValue);\n      }\n      return MAPPER.readValue(\n          MAPPER.writeValueAsString(ImmutableMap.of(\"options\", mapWithoutUrns)),\n          PipelineOptions.class);\n    } catch (IOException e) {\n      throw new RuntimeException(\"Failed to read PipelineOptions from Protocol\", e);\n    }\n  }\n\n  /** Converts the provided Json{@link String} into {@link PipelineOptions}. */\n  public static PipelineOptions fromJson(String optionsJson) {\n    try {\n      Map<String, Object> probingOptionsMap =\n          MAPPER.readValue(optionsJson, new TypeReference<Map<String, Object>>() {});\n      if (probingOptionsMap.containsKey(\"options\")) {\n        // Legacy options.\n        return MAPPER.readValue(optionsJson, PipelineOptions.class);\n      } else {\n        // Fn Options with namespace and version.\n        Struct.Builder builder = Struct.newBuilder();\n        JsonFormat.parser().merge(optionsJson, builder);\n        return fromProto(builder.build());\n      }\n    } catch (IOException e) {","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/PipelineOptionsTranslation.java#L89-L125","documentation":"fromProto converts a protobuf Struct of pipeline options back into PipelineOptions by round-tripping through Jackson (writeValueAsString then readValue into PipelineOptions). If the Jackson read/write throws IOException, Beam wraps it in a RuntimeException with this message, indicating the proto options could not be materialized into a PipelineOptions instance.","triggerScenarios":"Calling PipelineOptionsTranslation.fromProto/fromJson with a Struct whose values don't match the registered PipelineOptions bean properties (unknown types, malformed nodes) causing MAPPER.readValue to fail.","commonSituations":"Options produced by a different Beam version or SDK with incompatible option names/types; hand-edited pipeline JSON; missing PipelineOptionsRegistrar registrations for custom option classes.","solutions":["Check the wrapped IOException for the specific property deserialization failure","Ensure both pipeline ends use the same PipelineOptions classes registered via AutoService(PipelineOptionsRegistrar)","Verify the Struct contents match the expected {options: {urn: value}} layout produced by toProto"],"exampleFix":"// before\nfromProto(structWithUnknownOptions) // java.io.IOException at readValue\n// after\nStruct fixed = alignOptionKeysWithRegisteredInterfaces(struct); // then fromProto(fixed)","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { PipelineOptions o = PipelineOptionsTranslation.fromProto(struct); } catch (RuntimeException e) { log.error(\"proto->options failed\", e.getCause()); throw e; }","preventionTips":["Register custom option interfaces with PipelineOptionsRegistrar (AutoService)","Keep option classes identical on producer and consumer sides","Round-trip test fromProto(toProto(options)) in CI"],"tags":["java","apache-beam","pipeline-options","jackson","deserialization"],"backgroundTag":"json-unmarshal-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"}