diff --git a/src/openai/lib/_parsing/_completions.py b/src/openai/lib/_parsing/_completions.py
index c160070b66..67a687c6f1 100644
--- a/src/openai/lib/_parsing/_completions.py
+++ b/src/openai/lib/_parsing/_completions.py
@@ -158,7 +158,13 @@ def maybe_parse_content(
     message: ChatCompletionMessage | ParsedChatCompletionMessage[object],
 ) -> ResponseFormatT | None:
     if has_rich_response_format(response_format) and message.content and not message.refusal:
-        return _parse_content(response_format, message.content)
+        try:
+            return _parse_content(response_format, message.content)
+        except ValueError as e:
+            # if parsing fails due to whitespace content, log a warning and return None
+            import logging
+            logging.warning(f"Failed to parse content: {e}")
+            return None
 
     return None
 
@@ -217,6 +223,13 @@ def is_parseable_tool(input_tool: ChatCompletionToolParam) -> bool:
 
 
 def _parse_content(response_format: type[ResponseFormatT], content: str) -> ResponseFormatT:
+    # checking here if the content is empty or contains only whitespace
+    if not content or content.isspace():
+        raise ValueError(
+            f"Cannot parse empty or whitespace-only content as {response_format.__name__}. "
+            "The model returned content with no valid JSON."
+        )
+        
     if is_basemodel_type(response_format):
         return cast(ResponseFormatT, model_parse_json(response_format, content))
 
diff --git a/src/openai/lib/streaming/chat/_completions.py b/src/openai/lib/streaming/chat/_completions.py
index a7b70c32d3..abb41e1048 100644
--- a/src/openai/lib/streaming/chat/_completions.py
+++ b/src/openai/lib/streaming/chat/_completions.py
@@ -441,10 +441,13 @@ def _accumulate_chunk(self, chunk: ChatCompletionChunk) -> ParsedChatCompletionS
                 # partial parsing fails on white-space
                 and choice_snapshot.message.content.lstrip()
             ):
-                choice_snapshot.message.parsed = from_json(
-                    bytes(choice_snapshot.message.content, "utf-8"),
-                    partial_mode=True,
-                )
+                # skipping parsing if content is just whitespace
+                content = choice_snapshot.message.content
+                if content.strip():
+                    choice_snapshot.message.parsed = from_json(
+                        bytes(content, "utf-8"),
+                        partial_mode=True,
+                    )
 
             for tool_call_chunk in choice.delta.tool_calls or []:
                 tool_call_snapshot = (choice_snapshot.message.tool_calls or [])[tool_call_chunk.index]
@@ -459,10 +462,13 @@ def _accumulate_chunk(self, chunk: ChatCompletionChunk) -> ParsedChatCompletionS
                         and input_tool.get("function", {}).get("strict")
                         and tool_call_snapshot.function.arguments
                     ):
-                        tool_call_snapshot.function.parsed_arguments = from_json(
-                            bytes(tool_call_snapshot.function.arguments, "utf-8"),
-                            partial_mode=True,
-                        )
+                        arguments = tool_call_snapshot.function.arguments
+                        # skipping parsing if arguments is just whitespace
+                        if arguments.strip():
+                            tool_call_snapshot.function.parsed_arguments = from_json(
+                                bytes(arguments, "utf-8"),
+                                partial_mode=True,
+                            )
                 elif TYPE_CHECKING:  # type: ignore[unreachable]
                     assert_never(tool_call_snapshot)