Skip to content

ValueError: Circular reference detected with Gemini + file upload, and logs with large inline data blocking async event loop #1881

@anthony2261

Description

@anthony2261

Description

When google genai sdk is being logged, and a gemini call with a file upload is made, I get ValueError: Circular reference detected

Here's roughly how the code looks like:

# imports ... mainly what's needed
import io

import logfire
from google import genai
from google.genai import types
from pydantic import BaseModel

logfire.configure()
logfire.instrument_google_genai()

class TranscriptionResult(BaseModel):
    transcription: str
    reasoning: str

client = genai.Client(api_key=config.GOOGLE_GEMINI_API_KEY)

@logfire.instrument("Transcribe audio", extract_args=False)
async def transcribe_audio(audio_bytes: bytes)
    uploaded = client.files.upload(file=io.BytesIO(audio_bytes), config={"mime_type": "audio/wav"})
    gemini_response = await client.aio.models.generate_content(
        model="gemini-3-flash-preview",
        contents=["Transcribe this file", uploaded],
        config=types.GenerateContentConfig(
            response_mime_type="application/json",
            response_schema=TranscriptionResult,
            thinking_config=types.ThinkingConfig(thinking_budget=128),
        ),
    )
    return gemini_response.parsed

# Error happens when calling transcribe_audio

Full error log (with some files renamed):

ERROR:logfire:Caught an internal error in Logfire. Your code should still be running fine, just with less telemetry. This is just logging the internal error.
Traceback (most recent call last):
  File "/home/<project>/backend/.venv/lib/python3.11/site-packages/sentry_sdk/integrations/threading.py", line 123, in _run_old_run_func
    return old_run_func(self, *a[1:], **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/<project>/backend/.venv/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 967, in run
    result = context.run(func, *args)
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/<project>/backend/src/services/analyze_audio.py", line 72, in _analyze_audio
    gemini_response = client.models.generate_content(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/<project>/backend/.venv/lib/python3.11/site-packages/opentelemetry/instrumentation/google_genai/generate_content.py", line 1018, in instrumented_generate_content
    helper.process_request(contents, config, span)
  File "/home/<project>/backend/.venv/lib/python3.11/site-packages/opentelemetry/instrumentation/google_genai/generate_content.py", line 586, in process_request
    self._maybe_log_user_prompt(contents)
  File "/home/<project>/backend/.venv/lib/python3.11/site-packages/opentelemetry/instrumentation/google_genai/generate_content.py", line 830, in _maybe_log_user_prompt
    self._maybe_log_single_user_prompt(
  File "/home/<project>/backend/.venv/lib/python3.11/site-packages/opentelemetry/instrumentation/google_genai/generate_content.py", line 860, in _maybe_log_single_user_prompt
    self._otel_wrapper.log_user_prompt(
  File "/home/<project>/backend/.venv/lib/python3.11/site-packages/opentelemetry/instrumentation/google_genai/otel_wrapper.py", line 95, in log_user_prompt
    self._log_event(event_name, attributes, body)
  File "/home/<project>/backend/.venv/lib/python3.11/site-packages/opentelemetry/instrumentation/google_genai/otel_wrapper.py", line 110, in _log_event
    self._logger.emit(event)
  File "/home/<project>/backend/.venv/lib/python3.11/site-packages/logfire/_internal/integrations/google_genai.py", line 90, in emit
    span.add_event(record.event_name, attributes={'event_body': json.dumps(body, default=default_json)})
                                                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
          ^^^^^^^^^^^
  File "/usr/local/lib/python3.11/json/encoder.py", line 200, in encode
    chunks = self.iterencode(o, _one_shot=True)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/json/encoder.py", line 258, in iterencode
    return _iterencode(o, 0)
           ^^^^^^^^^^^^^^^^^
ValueError: Circular reference detected

Bonus: On a slow connection and for large audios, if I don't set extract_args=False, it blocks my async event loop (I'm using FastAPI) while it uploads the log. I even moved from gemini's inline audio upload to File API -> Gemini call because that also blocked the async loop while it was uploading. But not the main point of the bug.

Python, Logfire & OS Versions, related packages (not required)

logfire="4.32.1"
platform="Linux-6.6.87.2-microsoft-standard-WSL2-x86_64-with-glibc2.39"
python="3.11.11 (main, Mar 17 2025, 21:02:09) [Clang 20.1.0 ]"
[related_packages]
requests="2.33.1"
pydantic="2.11.7"
fastapi="0.136.1"
protobuf="6.33.6"
rich="14.1.0"
executing="2.2.0"
opentelemetry-api="1.40.0"
opentelemetry-exporter-otlp-proto-common="1.40.0"
opentelemetry-exporter-otlp-proto-http="1.40.0"
opentelemetry-instrumentation="0.61b0"
opentelemetry-instrumentation-asgi="0.61b0"
opentelemetry-instrumentation-fastapi="0.61b0"
opentelemetry-instrumentation-google-genai="0.7b0"
opentelemetry-instrumentation-httpx="0.61b0"
opentelemetry-instrumentation-requests="0.61b0"
opentelemetry-instrumentation-sqlalchemy="0.61b0"
opentelemetry-proto="1.40.0"
opentelemetry-sdk="1.40.0"
opentelemetry-semantic-conventions="0.61b0"
opentelemetry-util-genai="0.3b0"
opentelemetry-util-http="0.61b0"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions