langchain-ai/langchain · error · NotImplementedError

_type property is not implemented in class {self.__class__._

Error message

_type property is not implemented in class {self.__class__.__name__}. This is required for serialization.

What it means

The base `BaseOutputParser._type` property raises NotImplementedError by design; every serializable parser must override it with a short type identifier (e.g. `"boolean_output_parser"`, `"json"`). Serialization via `asdict()`/`dict()` embeds `_type` so the parser can be reconstructed on load, so calling those methods on a parser without `_type` fails. This is a subclass-contract error, not a runtime data error.

Source

Thrown at libs/core/langchain_core/output_parsers/base.py:345

            prompt: Input `PromptValue`.

        Returns:
            Structured output.
        """
        return self.parse(completion)

    def get_format_instructions(self) -> str:
        """Instructions on how the LLM output should be formatted."""
        raise NotImplementedError

    @property
    def _type(self) -> str:
        """Return the output parser type for serialization."""
        msg = (
            f"_type property is not implemented in class {self.__class__.__name__}."
            " This is required for serialization."
        )
        raise NotImplementedError(msg)

    @deprecated("1.4.2", alternative="asdict", removal="2.0.0")
    @override
    def dict(self, **kwargs: Any) -> builtins.dict[str, Any]:
        """DEPRECATED - use `asdict()` instead.

        Return a dictionary representation of the output parser.
        """
        return self.asdict(**kwargs)

    def asdict(self, **kwargs: Any) -> builtins.dict[str, Any]:
        """Return a dictionary representation of the output parser."""
        output_parser_dict = super().model_dump(**kwargs)
        with contextlib.suppress(NotImplementedError):
            output_parser_dict["_type"] = self._type
        return output_parser_dict

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Add `@property def _type(self) -> str: return "my_parser"` to your subclass.
  2. Use a unique, stable string if you plan to deserialize later, and register a loader for it.
  3. If serialization is not needed for this parser, avoid `asdict()`/checkpointing paths instead of leaving the contract unimplemented.

Example fix

// before
class MyParser(BaseOutputParser[str]):
    def parse(self, text): return text.strip()

// after
class MyParser(BaseOutputParser[str]):
    @property
    def _type(self) -> str: return "my_parser"
    def parse(self, text): return text.strip()
Defensive patterns

Strategy: validation

Validate before calling

def is_serializable_parser(p) -> bool:
    try:
        p._type
        return True
    except NotImplementedError:
        return False

if not is_serializable_parser(parser):
    raise ValueError(f"{type(parser).__name__} must define _type before checkpointing")

Try / catch

try:
    parser.asdict()
except NotImplementedError as e:
    if "_type" in str(e):
        # add _type to the subclass, or skip serializing this component
        ...

Prevention

When it happens

Trigger: Calling `parser.asdict()` (or deprecated `parser.dict()`) on a custom parser that does not define `_type`; passing such a parser through runnables that checkpoint/serialize their steps.

Common situations: Custom parsers built for a single chain and later pulled into LangGraph checkpointing; migrating persisted runnables that now serialize components they previously ignored.

Related errors


AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14). Data as JSON: /api/errors/3ba71c5b5d3dd8df. Report an issue: GitHub.