Get this on every PR automatically. Webhook fires, AI reviews, you approve.
Install on langchain-ai/deployment-cookbook →
// reviewed by pulllight
PullLight found 4 issues
2 high
1 medium
1 low
// convert to your repo
PullLight caught 4 2 high, 1 medium, 1 low on this PR.
Install on langchain-ai/deployment-cookbook to get this on every PR automatically — 60 seconds.
Findings
4 issues
high
auth
`getApiKey()` returns `undefined` when `LANGSMITH_API_KEY` is not set, and `createManagedClient()` silently passes `{ apiKey: undefined }` to `ManagedClient`. This means all API calls (fetchThreads, createThread, deleteThread, createStreamClient) will be made without authentication, likely resulting in 401 errors at runtime rather than a clear configuration error. The missing-key case should be caught early and surfaced to the user, similar to how `requireManagedAgentId()` works.
// js-langsmith-managed/src/lib/chat/threads-client.ts:43
high
auth
`envPrefix: ["VITE_", "LANGSMITH_"]` causes Vite to embed ALL environment variables whose names start with `LANGSMITH_` into the client bundle at build time. This includes `LANGSMITH_API_KEY`, which is a secret credential. When deployed to Vercel (as documented in the README), this key will be baked into the publicly-served JavaScript bundle and visible to anyone who inspects the page source. The README acknowledges this for local dev, but the Vercel deployment instructions in the README also set `LANGSMITH_API_KEY` as a Vercel env var, meaning the production build will also expose it. A backend proxy should be used instead of shipping the key to the browser in production builds.
// js-langsmith-managed/vite.config.ts:9
medium
race-condition
The `initStarted` ref guard prevents double-initialization in StrictMode, but `handleDelete` (line 68) calls `createThread()` and `fetchThreads()` without any guard. If the user rapidly deletes threads, multiple concurrent `createThread` calls can fire, creating orphaned threads. Additionally, `handleCreate` and `handleDelete` are not guarded against concurrent execution with each other.
// js-langsmith-managed/src/components/ChatApp.tsx:47
low
other
`threadId` is declared in the `Chat` component's props type but is never used inside the component body — only `onRunSettled` is consumed. The `threadId` prop is destructured nowhere and the component reads thread state entirely from `useStreamContext`. This is a dead prop that could mislead readers into thinking the component uses it for something (e.g. resetting state on thread change), when it does not.
// js-langsmith-managed/src/components/Chat.tsx:17