{"record":{"id":"4e28f440ee0e6065","repo":"apache/beam","slug":"unexpected-statespec","errorCode":null,"errorMessage":"Unexpected StateSpec {}","messagePattern":"Unexpected StateSpec (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/core/src/main/java/org/apache/beam/sdk/state/StateSpecs.java","lineNumber":357,"sourceCode":"   * <p>Convert a combining state spec to a bag of accumulators.\n   */\n  @Internal\n  public static <InputT, AccumT, OutputT> StateSpec<BagState<AccumT>> convertToBagSpecInternal(\n      StateSpec<CombiningState<InputT, AccumT, OutputT>> combiningSpec) {\n    if (combiningSpec instanceof CombiningStateSpec) {\n      // Checked above; conversion to a bag spec depends on the provided spec being one of those\n      // created via the factory methods in this class.\n      @SuppressWarnings(\"unchecked\")\n      CombiningStateSpec<InputT, AccumT, OutputT> typedSpec =\n          (CombiningStateSpec<InputT, AccumT, OutputT>) combiningSpec;\n      return typedSpec.asBagSpec();\n    } else if (combiningSpec instanceof CombiningWithContextStateSpec) {\n      @SuppressWarnings(\"unchecked\")\n      CombiningWithContextStateSpec<InputT, AccumT, OutputT> typedSpec =\n          (CombiningWithContextStateSpec<InputT, AccumT, OutputT>) combiningSpec;\n      return typedSpec.asBagSpec();\n    } else {\n      throw new IllegalArgumentException(\"Unexpected StateSpec \" + combiningSpec);\n    }\n  }\n\n  /**\n   * <b><i>For internal use only; no backwards-compatibility guarantees.</i></b>\n   *\n   * <p>Convert a set state spec to a map-state spec.\n   */\n  @Internal\n  public static <KeyT> StateSpec<MapState<KeyT, Boolean>> convertToMapSpecInternal(\n      StateSpec<SetState<KeyT>> setStateSpec) {\n    if (setStateSpec instanceof SetStateSpec) {\n      // Checked above; conversion to a map spec depends on the provided spec being one of those\n      // created via the factory methods in this class.\n      @SuppressWarnings(\"unchecked\")\n      SetStateSpec<KeyT> typedSpec = (SetStateSpec<KeyT>) setStateSpec;\n      return typedSpec.asMapSpec();\n    } else {","sourceCodeStart":339,"sourceCodeEnd":375,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/core/src/main/java/org/apache/beam/sdk/state/StateSpecs.java#L339-L375","documentation":"convertToBagSpecInternal converts a combining StateSpec into an equivalent bag StateSpec. It only recognizes the concrete internal spec types Beam itself creates (CombiningStateSpec / CombiningWithContextStateSpec); any other StateSpec implementation reaches the else branch and throws IllegalArgumentException. This is an internal-use invariant check protecting the conversion API.","triggerScenarios":"Passing a custom or foreign StateSpec implementation (not one of the specs produced by StateSpecs factory methods) into the bag-spec conversion path used internally when a CombiningState needs to be represented as a bag, e.g. during pipeline translation for partially-consumed combining state.","commonSituations":"Custom StateSpec subclasses or specs from third-party extensions flowing into internal conversion; version skew where a runner/plugin passes a spec class unknown to this code; misuse of internal-use-only APIs.","solutions":["Only create state specs via the StateSpecs factory methods; never pass custom StateSpec implementations.","If a custom spec is legitimately needed, extend the conversion to handle it (upstream change) or subclass one of the recognized spec classes.","Update/align the Beam SDK and runner versions so their internal StateSpec classes match."],"exampleFix":"// before\nStateSpec<Object> custom = new MyCustomSpec<>();\n\n// after\nStateSpec<CombiningState<...>> spec = StateSpecs.combining(coder, combineFn);","handlingStrategy":"validation","validationCode":"// Verify the spec is one of Beam's own factory-produced specs before conversion\nif (!(spec instanceof StateSpecs.CombiningStateSpec\n    || spec instanceof StateSpecs.CombiningWithContextStateSpec)) {\n  throw new IllegalArgumentException(\"spec must come from StateSpecs.combining(...)\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  bagSpec = convertToBagSpecInternal(spec);\n} catch (IllegalArgumentException e) {\n  // use the original spec instead of converting\n}","preventionTips":["Only build state specs with StateSpecs factory methods","Do not subclass StateSpec for custom behavior; use supported extension points","Keep Beam SDK and runner versions in sync"],"tags":["apache-beam","state-api","internal-api"],"backgroundTag":"internal-invariant-violation","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"}