<@ULVA73B9P> calling marvin.extract within a tool ...
# ask-marvin
d
@Marvin calling marvin.extract within a tool that is called by an agent results in the following error
Copy code
<Token var=<ContextVar name=‘current_thread’      │
│           default=None at 0x10c9bb010> at 0x12249dd00> was created in a different Context
please advise`
👀 1
m
thought for 179.2 seconds
d
side note: I wonder if I should just use
with marvin.Thread() as thread:
within this tool to scope internally to that tool.
m
Thanks for the report — that error is coming from Python’s ContextVar system and usually means the tool is being executed in a different thread/async context than the one where Marvin set its
current_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:
Copy code
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:
Copy code
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/marvin
n
Copy code
"""
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()
this doesn't appear to repro
is there something meaningfully different that you're doing?
d
checking
one thing for sure is memory
each agent has memory
n
hm ok. i would like to release that
marvin.Team
fix for you, if you can repro this i can hold off releasing so we can get this fixed first too
d
Feel free to proceed with the release. the more I look at this the more I think its user error. I think i’m getting too creative with the way tools work.
n
salute canada intensifies
fyi @datamongus i plan to deprecate teams and swarms since i dont think they work as advertised - would you have any issues with this?
d
is there an alternative?
n
for what outcomes?
d
I agree that they don’t work as advertised. Even after yesterday’s release I still had to revert back to my previous solution, behavior was a bit awkward.
I’m shooting for a team of agents that behave in a Team Leader + Specialist capacity. Single Turn execution with handoff of tasks.
I think current Swarm/Team implementation is on the naive side. Feels more like a true Swarm if you will.
Maybe I can contribute something if I can get my solution ironed out.