Skip to content

useAgent getHttpUrl() returns empty string before WebSocket connects, causing ai-chat to crash #1356

@IsraelHuentecura

Description

@IsraelHuentecura

Bug

useAgent() from agents/react returns an agent object where getHttpUrl() returns "" before the WebSocket connection is established. @cloudflare/ai-chat's useAgentChat() then does new URL(agent.getHttpUrl()) (line 516 of react.js) which throws TypeError: Failed to construct 'URL': Invalid URL.

This crashes the component on first render before the WebSocket has time to connect.

Reproduction

import { useAgent } from 'agents/react'
import { useAgentChat } from '@cloudflare/ai-chat/react'

function Chat() {
  const agent = useAgent({ agent: 'my-agent', name: 'test' })
  
  // This crashes immediately because agent.getHttpUrl() returns ""
  // and ai-chat does new URL("") internally
  const chat = useAgentChat({ agent })
  
  return <div>{/* ... */}</div>
}

Root cause

In agents@0.11.4, react.js line 264:

agent.getHttpUrl = () => {
  return (agent._url || agent._pkurl || "").replace("ws://", "http://").replace("wss://", "https://");
};

When neither _url nor _pkurl is set (before WebSocket connects), this returns "".

In @cloudflare/ai-chat@0.4.6, react.js line 516:

const agentUrl = new URL(agent.getHttpUrl());

new URL("") throws TypeError: Invalid URL.

Versions

  • agents@0.11.4
  • @cloudflare/ai-chat@0.4.6
  • @ai-sdk/react@3.0.170

Current workaround

We patch getHttpUrl in our useAgent wrapper to return a placeholder URL:

const nativeGetHttpUrlRef = useRef(theAgent.getHttpUrl)
theAgent.getHttpUrl = () => {
  const url = nativeGetHttpUrlRef.current?.() ?? ''
  return url || 'http://localhost'
}

Suggested fix

Either in agents:

agent.getHttpUrl = () => {
  const raw = (agent._url || agent._pkurl || "");
  if (!raw) return "about:blank"; // or throw a descriptive error
  return raw.replace("ws://", "http://").replace("wss://", "https://");
};

Or in ai-chat:

const rawUrl = agent.getHttpUrl();
const agentUrl = rawUrl ? new URL(rawUrl) : null;
// guard against null agentUrl downstream

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