Skip to content

fix(qdrant): support qdrant-client v1.12+ and handle removed methods gracefully#4004

Open
Koushik-Salammagari wants to merge 2 commits intotraceloop:mainfrom
Koushik-Salammagari:fix/qdrant-compat-v1-16
Open

fix(qdrant): support qdrant-client v1.12+ and handle removed methods gracefully#4004
Koushik-Salammagari wants to merge 2 commits intotraceloop:mainfrom
Koushik-Salammagari:fix/qdrant-compat-v1-16

Conversation

@Koushik-Salammagari
Copy link
Copy Markdown

@Koushik-Salammagari Koushik-Salammagari commented Apr 16, 2026

Summary

Fixes #3492

  • Removes upload_records from both qdrant_client_methods.json and async_qdrant_client_methods.json — this method was removed in qdrant-client 1.12 and caused an AttributeError on instrumentation startup
  • Wraps wrap_function_wrapper in try/except AttributeError so any future method removals in new qdrant-client releases degrade gracefully (logs a debug message and skips the method) instead of crashing the whole instrumentation
  • Updates the test dependency upper bound from <1.12 to <2 to allow testing against current qdrant-client releases
  • Adds span.record_exception() + StatusCode.ERROR to the wrapped call in wrapper.py (also addresses 🐛 Bug Report: Errors are not logged #412 for qdrant)

Test plan

  • Install qdrant-client>=1.12 and verify QdrantInstrumentor().instrument() completes without AttributeError
  • Verify remaining methods (upsert, search, query, etc.) still produce spans
  • Run existing test suite: npx nx run opentelemetry-instrumentation-qdrant:test

Summary by CodeRabbit

  • Bug Fixes

    • Spans now record exceptions and set error status when operations fail.
    • Instrumentation gracefully skips missing client methods to avoid failures.
    • Removed instrumentation for the upload_records operation (no span will be created).
  • Chores

    • Test dependencies updated to allow qdrant-client v1.x through v1.x (up to, but not including, v2).

…gracefully

- Remove upload_records from method lists (removed in qdrant-client 1.12)
- Wrap wrap_function_wrapper in try/except AttributeError so removed
  methods in future releases do not crash instrumentation on startup
- Update test dependency upper bound from <1.12 to <2
- Add error span recording (record_exception + StatusCode.ERROR) on
  wrapped call failures

Fixes traceloop#3492
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Apr 16, 2026

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 16, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 98bfe680-9beb-4b1e-9cad-7d8b406448f9

📥 Commits

Reviewing files that changed from the base of the PR and between 2080866 and 589df61.

📒 Files selected for processing (1)
  • packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/wrapper.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/wrapper.py

📝 Walkthrough

Walkthrough

Guarded method wrapping and removed obsolete method mappings for upload_records; spans now explicitly record exceptions and set error status on wrapped call failures; test dependency upper bound widened to allow qdrant-client <2.0.

Changes

Cohort / File(s) Summary
Instrumentation mappings
packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/async_qdrant_client_methods.json, packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/qdrant_client_methods.json
Removed mapping entries for AsyncQdrantClient.upload_records and QdrantClient.upload_records.
Instrumentation init & wrapping
packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/__init__.py, packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/wrapper.py
Added try/except around wrapt call to ignore AttributeError when target methods are absent; adjusted span creation to set record_exception=False/set_status_on_exception=False, wrap execution in try/except to record exceptions and set span status to ERROR, and removed upload_records-specific param handling.
Testing config
packages/opentelemetry-instrumentation-qdrant/pyproject.toml
Widened qdrant-client test dependency from <1.12 to <2.0 to allow newer client versions in test matrix.

Sequence Diagram(s)

sequenceDiagram
  participant App as Application
  participant Instr as QdrantInstrumentor
  participant Wrapt as wrapt
  participant Client as QdrantClient
  participant Tracer as Tracer/Span

  App->>Instr: instrument()
  Instr->>Wrapt: wrap_function_wrapper(target method)
  alt method exists
    Wrapt->>Client: replace method with wrapper
  else method missing
    Wrapt-->>Instr: AttributeError
    Instr-->>App: log debug, continue
  end
  App->>Client: call wrapped method(...)
  Client->>Tracer: Tracer.start_span(record_exception=False,set_status_on_exception=False)
  Tracer->>Client: execute original method
  alt method raises
    Client-->>Tracer: exception
    Tracer->>Tracer: record_exception + set Status(ERROR)
    Tracer-->>App: re-raise exception
  else success
    Tracer->>Tracer: set Status(OK) if response truthy
    Tracer-->>App: return response
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 In code I hop, I check each door,

If methods vanish, I patch once more.
I trace the call, and if it falls,
I mark the span and raise the calls.
A little hop for compatibility lore.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely summarizes the main changes: supporting qdrant-client v1.12+ and handling removed methods gracefully through defensive programming.
Linked Issues check ✅ Passed The PR directly addresses issue #3492 by removing the upload_records method entries from the JSON mappings and wrapping wrap_function_wrapper calls in try/except to handle AttributeError gracefully, preventing instrumentation crashes.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the qdrant-client compatibility issue: method removal handling, exception wrapping, span error handling, and test dependency updates are all within scope.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/wrapper.py`:
- Around line 73-76: In the exception handler in wrapper.py replace the
span.set_status call that includes str(e) with an error-only status (e.g., call
span.set_status(Status(StatusCode.ERROR)) or set_status(StatusCode.ERROR)
depending on the existing API) so only the error code is set while leaving
span.record_exception(e) intact; update the call sites using
span.record_exception and span.set_status (the try/except block containing
span.record_exception(e) and span.set_status(Status(StatusCode.ERROR, str(e))))
to remove the high-cardinality description.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e9c48b76-5867-4baf-b9a7-913fd1fdcc92

📥 Commits

Reviewing files that changed from the base of the PR and between 25189ad and 2080866.

📒 Files selected for processing (5)
  • packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/__init__.py
  • packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/async_qdrant_client_methods.json
  • packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/qdrant_client_methods.json
  • packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/wrapper.py
  • packages/opentelemetry-instrumentation-qdrant/pyproject.toml
💤 Files with no reviewable changes (2)
  • packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/async_qdrant_client_methods.json
  • packages/opentelemetry-instrumentation-qdrant/opentelemetry/instrumentation/qdrant/qdrant_client_methods.json

… status

- Add record_exception=False, set_status_on_exception=False to
  start_as_current_span so the manual try/except is the sole handler
- Drop str(e) from Status(StatusCode.ERROR) to avoid sensitive data
  leaking into span status descriptions

Addresses coderabbitai review feedback on traceloop#4004
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 Bug Report: opentelemetry-instrumentation-qdrant is incompatible with qdrant-client version 1.16.1

2 participants