{"record":{"id":"89171ca8177a2642","repo":"apache/beam","slug":"unknown-output-type-output-getclass","errorCode":null,"errorMessage":"Unknown output type: ${output.getClass()}","messagePattern":"Unknown output type: (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/TransformProvider.java","lineNumber":121,"sourceCode":"      return indexToPCollection.build();\n    } else if (output != null) {\n      // This is needed to support custom output types.\n      Map<TupleTag<?>, PValue> values = output.expand();\n      Map<String, PCollection<?>> returnMap = new HashMap<>();\n      for (Map.Entry<TupleTag<?>, PValue> entry : values.entrySet()) {\n        if (!(entry.getValue() instanceof PCollection)) {\n          throw new UnsupportedOperationException(\n              \"Unable to parse the output type \"\n                  + output.getClass()\n                  + \" due to key \"\n                  + entry.getKey()\n                  + \" not mapping to a PCollection\");\n        }\n        returnMap.put(entry.getKey().getId(), (PCollection<?>) entry.getValue());\n      }\n      return returnMap;\n    } else {\n      throw new UnsupportedOperationException(\"Unknown output type: \" + output.getClass());\n    }\n  }\n\n  default Map<String, PCollection<?>> apply(\n      Pipeline p, String name, RunnerApi.FunctionSpec spec, Map<String, PCollection<?>> inputs) {\n    return extractOutputs(\n        Pipeline.applyTransform(name, createInput(p, inputs), getTransform(spec, p.getOptions())));\n  }\n\n  default String getTransformUniqueID(RunnerApi.FunctionSpec spec) {\n    if (BeamUrns.getUrn(ExternalTransforms.ExpansionMethods.Enum.SCHEMA_TRANSFORM)\n        .equals(spec.getUrn())) {\n      ExternalTransforms.SchemaTransformPayload payload;\n      try {\n        payload = ExternalTransforms.SchemaTransformPayload.parseFrom(spec.getPayload());\n        if (PTransformTranslation.MANAGED_TRANSFORM_URN.equals(payload.getIdentifier())) {\n          try {\n            // ManagedSchemaTransform includes a schema field transform_identifier that includes the","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/TransformProvider.java#L103-L139","documentation":"extractOutputs expands a custom PTransform output's expand() map and hit an entry whose value is not a PCollection (the unsupported branch for arbitrary PValue outputs). The output object (and its non-PCollection expand value under the reported key) is the input at fault: the expansion service can only wire PCollection outputs back into its response.","triggerScenarios":"A transform's apply/expand returns null output; or returns a type not covered by the PCollection/POutput branches in extractOutputs.","commonSituations":"Custom transforms returning null on failure; third-party PTransform wrappers with nonstandard output types.","solutions":["Ensure the transform always returns a non-null PCollection or POutput.","Check the implementation for early-return/null paths on empty input.","Wrap the transform to produce a standard PCollection output.","Inspect output.getClass() in the message and handle that type upstream."],"exampleFix":"// before\nreturn condition ? transform.expand(input) : null;\n// after\nPCollection<T> result = transform.expand(input);\nreturn requireNonNull(result, \"transform output must not be null\");","handlingStrategy":"validation","validationCode":"if (output == null) throw new IllegalStateException(\"Transform produced no output\");\nif (!(output instanceof PCollection) && !(output instanceof POutput)) throw new IllegalStateException(\"Unsupported output type: \" + output.getClass());","typeGuard":"boolean hasExtractableOutput(Object out) { return out instanceof PCollection || out instanceof POutput; }","tryCatchPattern":"try { Map<String, PCollection<?>> outs = provider.extractOutputs(output); } catch (UnsupportedOperationException e) { log.error(\"No extractable output: {}\", e.getMessage()); throw new TransformContractException(e); }","preventionTips":["Never return null from PTransform.expand/apply","Unit-test that transforms produce outputs for representative inputs","Restrict the expansion service to transforms with standard outputs","Emit empty PCollections for empty-input cases"],"tags":["beam","expansion","pcollection"],"backgroundTag":"unexpected-response-shape","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}