Skip to content

Bug: ThreadProvider doesn't read NEXT_PUBLIC_* environment variables, breaking default configuration #233

Description

Description

The ThreadProvider component does not read NEXT_PUBLIC_API_URL and NEXT_PUBLIC_ASSISTANT_ID environment variables, while StreamProvider does. This inconsistency causes the Thread History panel to remain empty when the application is accessed without explicit query parameters in the URL.


Environment

  • Version: main branch (as of latest commit)
  • Node.js: v20.x
  • Next.js: v14.x
  • Browser: Chrome, Firefox (all browsers affected)

Steps to Reproduce

  1. Set environment variables in .env.local:

    NEXT_PUBLIC_API_URL=http://localhost:8383/api/v1/agent-protocol
    NEXT_PUBLIC_ASSISTANT_ID=my-assistant
  2. Start the development server:

    pnpm install
    pnpm dev
  3. Access the application WITHOUT query parameters:

    http://localhost:3000/chat
    
  4. Observe the Thread History panel (left sidebar)


Expected Behavior

  • Thread History panel should load and display threads from the API
  • The application should use environment variables as default configuration
  • Behavior should be consistent with StreamProvider (which correctly reads env vars)

This is the standard Next.js pattern for configuration:

  • Environment variables provide defaults
  • Query parameters can override defaults
  • Users can deploy without hardcoded URLs

Actual Behavior

  • Thread History panel shows a loading spinner indefinitely
  • No threads are loaded or displayed
  • The sidebar remains empty

Workaround: Manually append query parameters to the URL:

http://localhost:3000/chat?apiUrl=http://localhost:8383/api/v1/agent-protocol&assistantId=my-assistant

When query parameters are provided, Thread History works correctly.


Root Cause

StreamProvider (Working) ✅

File: src/providers/Stream.tsx

export function StreamProvider({ children }: PropsWithChildren) {
  const envApiUrl: string | undefined = process.env.NEXT_PUBLIC_API_URL;
  const envAssistantId: string | undefined = process.env.NEXT_PUBLIC_ASSISTANT_ID;

  const [apiUrl] = useQueryState("apiUrl", {
    defaultValue: envApiUrl || "",
  });
  const [assistantId] = useQueryState("assistantId", {
    defaultValue: envAssistantId || "",
  });
  // ...
}

✅ Reads environment variables
✅ Passes them as defaultValue to useQueryState
✅ Works with and without query parameters

ThreadProvider (Broken) ❌

File: src/providers/Thread.tsx (lines 36-40)

export function ThreadProvider({ children }: PropsWithChildren) {
  const [apiUrl] = useQueryState("apiUrl");  // ❌ No defaultValue
  const [assistantId] = useQueryState("assistantId");  // ❌ No defaultValue
  const [threadId] = useQueryState("threadId");
  // ...
}

❌ Does NOT read environment variables
❌ No defaultValue provided to useQueryState
❌ Only works when query parameters are explicitly provided


Impact

Users Affected

  • Anyone deploying the application with environment-based configuration
  • Teams that want clean URLs without query parameters
  • Production deployments using Next.js environment variables

Severity

Medium - Core feature (Thread History) is broken in default configuration

Workarounds

  1. Manual Query Parameters (user-facing):

    • Append ?apiUrl=...&assistantId=... to every URL
    • Requires user education and bookmarking
    • Not scalable
  2. URL Rewriting (server-side):

    • Implement redirect rules to inject query parameters
    • Adds complexity and fragility
    • Doesn't fix the underlying issue
  3. Patch ThreadProvider (our temporary solution):

    • Modify Thread.tsx to match StreamProvider pattern
    • Works correctly but requires maintenance on updates

Proposed Fix

Apply the same pattern used in StreamProvider to ThreadProvider:

export function ThreadProvider({ children }: PropsWithChildren) {
  // Read environment variables
  const envApiUrl: string | undefined = process.env.NEXT_PUBLIC_API_URL;
  const envAssistantId: string | undefined = process.env.NEXT_PUBLIC_ASSISTANT_ID;

  // Pass env vars as defaultValue
  const [apiUrl] = useQueryState("apiUrl", {
    defaultValue: envApiUrl || "",
  });
  const [assistantId] = useQueryState("assistantId", {
    defaultValue: envAssistantId || "",
  });
  const [threadId] = useQueryState("threadId");
  
  // ... rest of the implementation
}

Changes Required

  1. Read process.env.NEXT_PUBLIC_API_URL and process.env.NEXT_PUBLIC_ASSISTANT_ID
  2. Pass env vars as defaultValue options to useQueryState
  3. Ensure backward compatibility (query parameters should still override env vars)

Benefits

  • ✅ Consistent with StreamProvider behavior
  • ✅ Follows Next.js conventions for environment variables
  • ✅ Backward compatible (query parameters still work)
  • ✅ Minimal code change (6 lines)
  • ✅ No breaking changes

Testing

Test Case 1: Environment Variables Only

# .env.local
NEXT_PUBLIC_API_URL=http://localhost:8383/api/v1/agent-protocol
NEXT_PUBLIC_ASSISTANT_ID=my-assistant

URL: http://localhost:3000/chat

Expected: Thread History loads ✅
Current: Thread History empty ❌

Test Case 2: Query Parameters (Backward Compatibility)

URL: http://localhost:3000/chat?apiUrl=http://localhost:8383/api/v1/agent-protocol&assistantId=my-assistant

Expected: Thread History loads ✅
Current: Thread History loads ✅

Test Case 3: Query Parameters Override Environment Variables

# .env.local
NEXT_PUBLIC_API_URL=http://default-api.example.com
NEXT_PUBLIC_ASSISTANT_ID=default-assistant

URL: http://localhost:3000/chat?apiUrl=http://override-api.example.com&assistantId=override-assistant

Expected: Uses query parameter values (not env vars) ✅
Current: N/A (no env var support) ❌


Related Issues

  • None found (please link if this is a duplicate)

Additional Context

This inconsistency was discovered while integrating the Agent Chat UI with a backend API. The StreamProvider correctly loads and displays messages, but the ThreadProvider fails to load thread history, causing a confusing user experience where some features work and others don't.

The fix is straightforward and mirrors the existing pattern in StreamProvider, ensuring consistent behavior across the application.


Checklist

  • I have checked for duplicate issues
  • I have provided reproduction steps
  • I have tested the proposed fix locally
  • I am willing to submit a PR with this fix

References

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions