Hi, I would like to ask you about this error and h...
# ask-ai
h
Hi, I would like to ask you about this error and how to avoid it:
Copy code
node_modules/@livekit/agents/src/stream/deferred_stream.ts:52
throw new Error('Stream source already set');
(note: it worked with 0.x version of node.js) Steps to reproduce: 1. use
multi_agent.ts
(from agents-js/examples/src/, main branch) 2. use this session: const session = new voice.AgentSession({llm: new openai.realtime.RealtimeModel(),userData: userdata}); 3. in session.start, add
inputOptions.closeOnDisconnect
as
false
4. remove whole
prewarm
step in
defineAgent
5. create node.js endpoint, ask for a new token:
Copy code
const at = new AccessToken(process.env.LIVEKIT_API_KEY, process.env.LIVEKIT_API_SECRET, {
      identity: userId,
    });
    at.addGrant({ roomJoin: true, room: `room-of-${userId}` });
    const roomConfig = new RoomConfiguration({
      agents: [
        new RoomAgentDispatch({
          agentName: "my-agent",
        }),
      ],
      departureTimeout: 180,
      emptyTimeout: 5,
    });
    at.roomConfig = roomConfig;
const token = await at.toJwt();
    return res.json({ token });
6. on front end, run LiveKitRoom from "@livekit/components-react" like this:
Copy code
<LiveKitRoom token={liveKitToken} serverUrl={process.env.LIVEKIT_URL} audio={true}>
          <RoomAudioRenderer />
        </LiveKitRoom>
7. fetch token, save it into react state, use it in LiveKitRoom 8. agent starts, you can talk, etc. 9. disconnect the user and let him to connect back (refresh the browser), that means we use same userId, same identity, same room name, but fresh token 10. server error 'Stream source already set'
t
Thanks for reaching out, Pavel. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
I understand how the "Stream source already set" error can be a bit confusing. This happens because the
DeferredReadableStream
class in the LiveKit agents SDK is designed to prevent attaching multiple sources to the same stream, which usually comes up during reconnection or when reusing stream instances. Here’s a simple way to work through this: 1. Before you call
setSource
again during reconnection, make sure to detach the previous source by using
detachSource()
on your
DeferredReadableStream
instance. 2. The
detachSource
method helps by releasing the reader lock, which cleans up the earlier stream attachment. 3. Once you’ve detached the old source, it’s safe to call
setSource
with a new stream. It’s likely that this is happening in your agent-side logic (like AI agents handling media streams) rather than the usual participant reconnection flow. Just a friendly reminder to double-check that your custom stream management code carefully handles the lifecycle states, so you don’t accidentally try to assign a new stream source without detaching the existing one first. I hope this helps clarify things! Sources: Managing participants | LiveKit Docs | pkg/rtc/room.go | src/room/events.ts | livekit-android-sdk/src/main/java/io/livekit/android/room/RTCEngine.kt | agents/src/stream/deferred_stream.ts
h
how to do it, do you have a code snippet ? I do not work with setSource or DeferredReadableStream in my code
t
I understand that encountering the error "Stream source already set" can be a bit frustrating, especially when you're not directly working with
setSource
or
DeferredReadableStream
. This usually happens because of some internal agent processes, like when the agent is reinitializing or when stream objects are being reused. Let's walk through some steps to help you resolve this: 1. First, try to identify which part of your setup might be causing the issue. For instance, methods such as
AgentActivity.attachAudioInput()
or
SpeechStream.updateInputStream()
internally call
setSource
. If these are reused without proper cleanup, it can lead to this error. 2. Make sure to clean up properly before reusing streams. Here are a few tips: ◦ Before attaching a new audio stream in
AgentActivity
, call
detachAudioInput()
. ◦ In
SpeechStream
, use
detachInputStream()
before you call
updateInputStream()
again. ◦ Consider using an
AbortController
in
SynthesizeStream
to help with cleanup. 1. Take a look at how your agent session restarts. Ensuring that streams and components are properly torn down before starting again can make a big difference. 2. It might also help to enable logging so you can trace exactly when streams are set or detached. This can give you clues about which internal component might be causing the problem. If you’d like, feel free to share more details about the specific agent or stream-related components you’re working with. I’d be happy to offer more tailored advice or code examples to help you out! Sources: agents/src/voice/room_io/_input.ts | livekit-agents/livekit/agents/voice/agent_session.py