Migrating to DSPy 3.3.0
Version 3.3.0 introduces 7 breaking changes. This guide details how to update your code.
Released: 8/3/2026
⚠️ Check Your Code
If you use any of these symbols, you need to read this guide:
dspy.Imagedspy.Audiodspy.Filedspy.LMRequestdspy.LMResponsedspy.BaseLMdspy.LMErrordspy.Flexdspy.GEPAdspy.Predictdspy.RLMdspy.CodeInterpreterdspy.PythonInterpreterdspy.ReActV2dspy.Historydspy.Tooldspy.ToolCallsdspy.ToolCallResultsdspy.contextdspy.dump_statedspy.load_statedspy.LMToolCallPartBreaking Changes
●Issue #1
Resource construction and validation for dspy.Image, dspy.Audio, and dspy.File no longer implicitly read local files or fetch remote URLs from path/URL strings. To load resources, use explicit factory methods like `Image.from_path(path)`, `Image.from_url(url)`, `Audio.from_path(path)`, `Audio.from_url(url)`, and `File.from_path(path)`. Existing `Image(url)` or `Image(url=url)` will now preserve a non-downloading provider-fetched URL reference.
●Issue #2
NumPy-backed features from the base install are no longer available. Users should explicitly import NumPy.
●Issue #3
Inspection of detailed GEPA results is no longer directly supported. Users should refer to the new Flex optimization capabilities.
●Issue #4
Direct construction of code interpreters is deprecated. Use `dspy.CodeInterpreter` within a Flex module or other appropriate contexts.
●Issue #5
Catching provider-specific LM exceptions is deprecated. Use the new `dspy.LMError` or its narrower DSPy subclasses.
●Issue #6
The custom next_tool_args and custom trajectory syntax in ReAct are replaced by dspy.History, dspy.Tool, and dspy.ToolCalls.
●Issue #7
The untyped LM boundary based on `prompt`, `messages`, and provider-shaped `kwargs` is being replaced by a typed, provider-neutral contract: `def forward(self, request: dspy.LMRequest) -> dspy.LMResponse:`.
Migration Steps
- 1Update `Image` construction from `Image(path)` or `Image(url=path)` to `Image.from_path(path)`.
- 2Update `Image` construction from `Image(url, download=True)` to `Image.from_url(url)`.
- 3Update `Image` construction from `Image.from_url(url)` or `Image.from_url(url, download=False)` to `Image(url)` or `Image(url=url)` to preserve non-downloading URL references.
- 4Update `Audio` construction from `Audio(path)` to `Audio.from_path(path)`.
- 5Update `Audio` construction from `Audio(url)` to `Audio.from_url(url)`.
- 6Update `File` construction from `File(path)` to `File.from_path(path)`.
- 7Explicitly import NumPy if you were relying on NumPy-backed features from the base install.
- 8Refactor code that directly constructs code interpreters to use `dspy.CodeInterpreter` within appropriate contexts, potentially within a Flex module.
- 9Update exception handling to catch `dspy.LMError` or its subclasses instead of provider-specific LM exceptions.
- 10Replace custom `next_tool_args` and trajectory syntax in ReAct with `dspy.History`, `dspy.Tool`, and `dspy.ToolCalls`.
- 11For custom LM authors, adapt to the new typed LM boundary: `def forward(self, request: dspy.LMRequest) -> dspy.LMResponse:`.
- 12If using `RLM(max_iterations=...)`, review its behavior in the context of Flex or other interpreter sandboxes.
- 13Review code that consumes raw Responses API tool-call outputs for compatibility with new shapes and typed objects.
- 14If you previously relied on implicit I/O for `Image`, `Audio`, or `File` construction from paths or URLs, update to use the explicit factory methods.
Release Summary
DSPy 3.3.0 introduces Flex for experimental program structure optimization and ReActV2 for native tool-calling. It also advances towards a typed, provider-neutral LM system and decouples LiteLLM.
Need More Details?
View the full release notes and all changes for DSPy 3.3.0.
View Full Changelog