datamongus
08/27/2025, 2:40 PM<Token var=<ContextVar name=‘current_thread’ │
│ default=None at 0x10c9bb010> at 0x12249dd00> was created in a different Context
please advise`Marvin
08/27/2025, 2:40 PMdatamongus
08/27/2025, 2:41 PMwith marvin.Thread() as thread:
within this tool to scope internally to that tool.Marvin
08/27/2025, 2:43 PMcurrent_thread
context. In practice, this often happens when a tool runs in a thread pool and then tries to call marvin.extract
(which manages/conveys the “current thread” context for LLM calls).
Concrete ways to fix/work around it:
- Prefer the async API inside tools
- If your tool can be async, make it async def
and call await marvin.extract_async(...)
. This keeps everything in the same task/context and avoids the thread handoff that triggers the error.
- Example:
from marvin import extract_async
async def parse_invoice(text: str):
# Give the inner call its own Marvin thread name to avoid relying on a ContextVar
return await extract_async(
data=text,
target=InvoiceModel,
thread="tool:parse-invoice"
)
- If your tool must be sync, decouple from the agent’s ContextVar by passing an explicit thread
- Giving the inner call its own Marvin thread (string or a new Thread object) avoids relying on the current_thread
ContextVar that the agent set:
from marvin import extract
def parse_invoice(text: str):
return extract(
data=text,
target=InvoiceModel,
thread="tool:parse-invoice" # any stable string ID works
)
- This prevents Marvin from trying to read/reset a ContextVar token across threads.
- Avoid running the tool in a thread pool if possible
- Some agent frameworks execute tools in a ThreadPoolExecutor by default. If there’s an option to run tools inline/on the same event loop, use that so Marvin’s context is preserved.
- If you must run sync code and can’t change the executor behavior, prefer the “explicit thread” approach above.
- Upgrade Marvin
- Make sure you’re on the latest Marvin, in case you’re hitting something we’ve improved recently: pip install -U marvin
- Repo: PrefectHQ/marvin
If you can share a minimal snippet (how the agent is created, how the tool is defined, sync vs async, and your Marvin version), I can tailor the recommendation and confirm the safest pattern for your setup.
Related references:
- Python ContextVars (background on the error): Python ContextVars docs
- Marvin repo (for latest changes/issues): PrefectHQ/marvinNate
08/27/2025, 2:46 PM"""
Reproduce context error when calling marvin.extract within a tool that is called by an agent.
Error: "Token var=<ContextVar name='current_thread' default=None> was created in a different Context"
"""
from pydantic import BaseModel
import marvin
class ExtractedInfo(BaseModel):
name: str
age: int | None = None
def extract_info_from_text(text: str) -> str:
"""Extract structured information from text using marvin.extract."""
# This should trigger the context error when called by an agent
extracted = marvin.extract(
data=text,
target=ExtractedInfo,
instructions="Extract name and age from the text",
)
return f"Extracted: {extracted}"
def main():
# Create an agent with the extract tool
agent = marvin.Agent(
name="ExtractorAgent",
tools=[extract_info_from_text],
instructions="You are a helpful assistant that extracts information from text.",
)
# Try to use the agent to call the tool
result = agent.run("Please extract info from this text: 'John is 25 years old'")
print(f"Result: {result}")
if __name__ == "__main__":
main()
Nate
08/27/2025, 2:46 PMNate
08/27/2025, 2:46 PMdatamongus
08/27/2025, 2:53 PMdatamongus
08/27/2025, 2:54 PMdatamongus
08/27/2025, 2:54 PMNate
08/27/2025, 3:15 PMmarvin.Team
fix for you, if you can repro this i can hold off releasing so we can get this fixed first toodatamongus
08/27/2025, 3:44 PMNate
08/27/2025, 3:59 PMNate
08/27/2025, 4:41 PMNate
08/28/2025, 3:17 PMdatamongus
08/28/2025, 3:36 PMNate
08/28/2025, 3:36 PMdatamongus
08/28/2025, 3:37 PMdatamongus
08/28/2025, 3:38 PMdatamongus
08/28/2025, 3:38 PMdatamongus
08/28/2025, 3:39 PM