Skip to content

withTracing wrapper loses getter properties from LanguageModelV2 #2816

@np-sage

Description

@np-sage

Bug description

The withTracing wrapper in @posthog/ai uses object spread ({...model}) to wrap Vercel AI SDK language models. This causes getter properties defined on the model's prototype (like provider and supportedUrls) to be lost, resulting in runtime errors when the AI SDK tries to access these properties on the wrapped model.

Error:

TypeError: Cannot convert undefined or null to object
    at Function.entries (<anonymous>)
    at isUrlSupported
    at downloadAssets
    at convertToLanguageModelPrompt
    at generateObject

Root cause: The GoogleGenerativeAILanguageModel class (from @ai-sdk/google) defines provider and supportedUrls as getters on the prototype:

class GoogleGenerativeAILanguageModel {
  constructor(modelId, config) {
    this.specificationVersion = "v2";
    this.modelId = modelId;
    this.config = config;
  }
  get provider() { return this.config.provider; }
  get supportedUrls() { return this.config.supportedUrls?.() ?? {}; }
}

The withTracing wrapper uses object spread which only copies own enumerable properties, not prototype getters:

// @posthog/ai/dist/vercel/index.cjs line 669
const wrappedModel = {
    ...model,
    doGenerate: async params => { ... },
    doStream: async params => { ... }
};

So wrappedModel.supportedUrls becomes undefined. When the AI SDK calls Object.entries(model.supportedUrls) for file handling, it crashes.

How to reproduce

  1. Wrap a Google Vertex AI model with withTracing
  2. Call generateObject or generateText with a file part (e.g., PDF, image)
  3. The AI SDK crashes when trying to check URL support

Minimal reproduction:

import { createVertex } from "@ai-sdk/google-vertex";
import { withTracing } from "@posthog/ai";
import { generateObject } from "ai";
import { z } from "zod";

const vertex = createVertex({ project: "my-project", location: "us-central1" });
const model = vertex("gemini-2.0-flash");

console.log(model.supportedUrls); // { "*": [/^https?:\/\/.*$/, /^gs:\/\/.*$/] }

const wrapped = withTracing(model, posthogClient, { posthogPrivacyMode: true });
console.log(wrapped.supportedUrls); // undefined ← BUG

// Crashes when processing file parts
await generateObject({
  model: wrapped,
  messages: [{
    role: "user",
    content: [
      { type: "text", text: "Describe this document" },
      { type: "file", data: new URL("gs://bucket/file.pdf"), mediaType: "application/pdf" }
    ]
  }],
  schema: z.object({ description: z.string() }),
});

Related sub-libraries

  • All of them
  • posthog-js (web)
  • posthog-js-lite (web lite)
  • posthog-node
  • posthog-react-native
  • @posthog/react
  • @posthog/ai
  • @posthog/nextjs-config
  • @posthog/nuxt
  • @posthog/rollup-plugin
  • @posthog/webpack-plugin

Additional context

Versions:

  • @posthog/ai: 7.3.0
  • ai (Vercel AI SDK): 5.0.108
  • @ai-sdk/google-vertex: 3.0.86
  • Node.js 22

Suggested fix: Forward getter properties after wrapping:

const wrappedModel = { ...model, doGenerate, doStream };

// Forward getters lost during spread
Object.defineProperty(wrappedModel, 'provider', {
    get() { return model.provider; },
    enumerable: true,
});
Object.defineProperty(wrappedModel, 'supportedUrls', {
    get() { return model.supportedUrls; },
    enumerable: true,
});

Or more robustly, enumerate all prototype getters and forward them:

const proto = Object.getPrototypeOf(model);
for (const [key, desc] of Object.entries(Object.getOwnPropertyDescriptors(proto))) {
    if (desc.get && !['doGenerate', 'doStream'].includes(key)) {
        Object.defineProperty(wrappedModel, key, {
            get() { return model[key]; },
            enumerable: true,
        });
    }
}

Workaround: Until fixed, users can manually forward the getters after calling withTracing.

Impact: This breaks all file/image processing when using @posthog/ai with Google Vertex AI (and likely other providers that define getter properties). It's production-breaking for any multimodal AI application using PostHog LLM analytics.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingllmoThis issue is related to LLM Observability.team/llm-analyticsLLM Analytics

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions