{"record":{"id":"0e163a6ae3431970","repo":"langchain-ai/langchain","slug":"asynctextprojection-requires-a-string-delta","errorCode":null,"errorMessage":"AsyncTextProjection requires a string delta","messagePattern":"AsyncTextProjection requires a string delta","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/language_models/chat_model_stream.py","lineNumber":522,"sourceCode":"    async def __anext__(self) -> str:\n        \"\"\"Return the next text delta.\"\"\"\n        item = await super().__anext__()\n        if not isinstance(item, str):\n            msg = \"AsyncTextProjection received a non-string delta\"\n            raise TypeError(msg)\n        return item\n\n\nclass AsyncTextProjection(AsyncProjection):\n    \"\"\"String-specialized async projection for `.text` and `.reasoning`.\"\"\"\n\n    __slots__ = ()\n\n    def push(self, delta: str) -> None:\n        \"\"\"Append a text delta and notify waiters.\"\"\"\n        if not isinstance(cast(\"Any\", delta), str):\n            msg = \"AsyncTextProjection requires a string delta\"\n            raise TypeError(msg)\n        super().push(delta)\n\n    def complete(self, final_value: str) -> None:\n        \"\"\"Set the final accumulated text and notify waiters.\"\"\"\n        if not isinstance(cast(\"Any\", final_value), str):\n            msg = \"AsyncTextProjection requires a string final value\"\n            raise TypeError(msg)\n        super().complete(final_value)\n\n    def __aiter__(self) -> _AsyncTextProjectionIterator:\n        \"\"\"Return an async iterator over text deltas.\"\"\"\n        return _AsyncTextProjectionIterator(self)\n\n    def __await__(self) -> Generator[Any, None, str]:\n        \"\"\"Await the full accumulated text.\"\"\"\n        return self._await_text_impl().__await__()\n\n    async def _await_text_impl(self) -> str:","sourceCodeStart":504,"sourceCodeEnd":540,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/language_models/chat_model_stream.py#L504-L540","documentation":"`TypeError` from `AsyncTextProjection.push`: a producer pushed a delta that is not a `str` into the string-specialized async projection used for `.text`/`.reasoning` in streaming chat model code. The runtime check mirrors the sync version (errorIndex 73) and fails fast on producer API-contract violations.","triggerScenarios":"Adapter/integration code calling `projection.push(value)` with an `AIMessageChunk`, `None`, bytes, or a dict instead of the extracted string. Typically happens in custom chat model implementations or when reusing the streaming internals directly.","commonSituations":"Custom async model integration pushing whole chunks instead of `chunk.text`; forgetting None-checks on optional chunk fields; porting sync adapter code that used untyped buffers.","solutions":["Push the extracted string: `projection.push(chunk.text)`; guard optional content first (`if chunk.text: ...`).","Type your producer code so `push` only ever sees `str` (mypy will catch violations at development time).","Use the generic `AsyncProjection` if you must push non-string values."],"exampleFix":"# before\nprojection.push(chunk)  # non-string AIMessageChunk\n\n# after\nif chunk.text:\n    projection.push(chunk.text)","handlingStrategy":"type-guard","validationCode":"assert isinstance(delta, str), f\"delta must be str, got {type(delta).__name__}\"\nprojection.push(delta)","typeGuard":"def is_text_delta(v: object) -> bool:\n    \"\"\"True when v can be pushed into an AsyncTextProjection.\"\"\"\n    return isinstance(v, str)","tryCatchPattern":"null","preventionTips":["Push chunk.text (guarded), never the chunk object","Type-hint producer callbacks as str-only","Keep one push helper per adapter so validation lives in one place"],"tags":["streaming","async","typeerror","internal-api"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}