fancy-easter-44489
02/24/2026, 4:55 AMtall-airline-16756
02/24/2026, 4:55 AMtall-airline-16756
02/24/2026, 4:55 AMtransfer_sip_participant. If the participant has hung up, the transfer will fail with this 404.
• Verify you are using the exact room_name and participant_identity that were used to create the SIP participant. Any mismatch will result in “unknown call.”
• Ensure the transfer is attempted before any session cleanup, room deletion, or job end that would remove the call context.
What to inspect next (step-by-step)
1. Check participant state before transfer
◦ Log or fetch the participant’s connection state immediately before calling transfer_sip_participant. Look for anything like a sip.callStatus of hangup (or equivalent) that shows the call already ended.
1. Confirm identifiers
◦ Print/log the room_name and participant_identity passed in your TransferSIPParticipantRequest and compare them to the values used when the SIP participant was created. The strings must match exactly.
1. Check timing / lifecycle
◦ Make sure the transfer is performed during the active agent job context and before any cleanup tasks run. If you create a SIP participant in one step and then later delete or close the room before transfer, the call will be gone.
1. Review SIP provider capabilities
◦ Confirm your SIP trunk/carrier supports SIP REFER (PSTN transfer) if your workflow relies on that. Carrier-side rejection won’t usually produce this exact error, but it’s worth confirming if transfers intermittently fail.
1. Collect relevant logs/traces
◦ Capture the sequence of events for a failing case: participant join, any attribute changes, hangup (if any), then the transfer attempt. These will show whether the call was still active at transfer time.
If you want, provide these items and I’ll dive deeper
• The exact room_name and participant_identity used for a failing attempt (obscure any sensitive tokens).
• The log lines showing participant join and the immediate log lines just before the transfer call.
• The snippet that builds the TransferSIPParticipantRequest (the fields you are populating).
• Whether your SIP provider requires/refuses REFER transfers (carrier name or configuration detail).
I can then point to the exact place in your flow where the call context is lost or suggest a code change to guard the transfer behind a participant-state check.
Sources: SIP Lifecycle Management Agent | LiveKit Documentation | Agents telephony integration | LiveKit Documentation | Pass UUI data to Genesys Cloud during SIP transfers | LiveKitfancy-easter-44489
02/24/2026, 5:00 AMtall-airline-16756
02/24/2026, 5:01 AMparticipant_identity (or the SIP participant identity) you are trying to transfer in that room? Please obfuscate any sensitive tokens if needed.
• At the moment you call transfer_sip_participant, is the SIP participant definitely still connected? Can you share the log lines (or a short excerpt) showing the participant join and the lines immediately before the transfer attempt for the failing case?
• Do you create the SIP participant in that same room earlier in your flow? If so, does the `room_name`/`roomId` used to create the SIP participant exactly match RM_HFwh82dyw97U?
• Does your SIP provider/carrier require or block SIP REFER transfers (PSTN transfer)? If you know the carrier or settings (e.g., Twilio with Call Transfer enabled), please mention it.
While you collect that, try these quick checks which commonly resolve this 404:
1. Immediately before calling transfer_sip_participant, fetch or log the participant state and confirm there’s no sip.callStatus of hangup (or equivalent disconnected state).
2. Print the exact room_name and participant_identity you pass into the TransferSIPParticipantRequest and compare to the created SIP participant values — they must match exactly.
3. Ensure the transfer is issued before any room cleanup or job end that might remove the call context.
If you paste:
• the participant identity,
• the small log snippet around join → transfer,
• and the code that constructs the TransferSIPParticipantRequest (just the fields),
I’ll analyze them and point to the exact place the call context is lost or give a code guard you can add to avoid the 404.fancy-easter-44489
02/24/2026, 5:02 AMtall-airline-16756
02/24/2026, 5:03 AMtransfer_sip_participant for room RM_HFwh82dyw97U.
• The code you shared that selects a participant by iterating job_ctx.room.remote_participants and then calls the transfer.
Root cause (concise)
• The SIP participant identity you pass to TransferSIPParticipantRequest can be stale or not a SIP leg at transfer time. Your loop overwrites p_identity with every remote participant but does not confirm the participant is a SIP participant or still connected when you call transfer. If the SIP leg has already ended or the identity is wrong, LiveKit returns 404 unknown call.
Immediate fixes (apply these in this order)
1) Select and validate an active SIP participant before transfer
• Don’t just take the last participant. Find a participant whose kind is SIP and confirm it’s still connected immediately before the transfer.
• Example pattern to use (pseudocode; adapt to your SDK objects):
sip_participant = None
for p in job_ctx.room.remote_participants.values():
if getattr(p, "kind", None) == ParticipantKind.PARTICIPANT_KIND_SIP:
sip_participant = p
break
if not sip_participant:
logger.error("No SIP participant found in room - cannot transfer.")
await self.session.say("I’m sorry — I can’t transfer the call right now.")
return
# optional: check sip_participant.connection_state or sip.callStatus if available
p_identity = sip_participant.identity
2) Check presence/state right before calling transfer
• Immediately before you call await livekit_api.sip.transfer_sip_participant(...), re-check that the participant is still present in job_ctx.room.remote_participants and that their call state is not hangup (or disconnected). Log the current participants on failure to capture race conditions.
3) Remove or stop relying on headers in TransferSIPParticipantRequest
• The headers field you pass is ignored for SIP transfers; it will not be delivered as you expect. If you need to pass transfer metadata (summary, CLI), put it into the transfer URI query parameters or use provider-specific mechanisms (e.g., Genesys UUI via URI parameters, Five9 via attributes→headers mapping).
• Example: build transfer_to like sip:123456789@domain?uui={encoded_summary} if your trunk supports it.
4) Add robust error logging and a guarded retry (optional)
• On failure, log the room participant list and their states:
logger.error(f"Transfer failed for {p_identity}: {e}. Current participants: {[p.identity for p in job_ctx.room.remote_participants.values()]}")
• If appropriate, a short retry (100–300ms) after verifying the participant still exists can sometimes recover from small race windows. Only retry if you confirm the participant is still present.
Why these changes will fix the 404
• The 404 is raised when there is no current SIP call for the participant identity and room. Selecting the correct participant type and verifying presence removes the race that produces stale identities. Removing unsupported headers avoids relying on functionality that isn’t used by the SIP transfer path.
Extra checks to perform
• Confirm your trunk/carrier supports SIP REFER or the transfer mechanism you expect (carrier-side settings can block transfers).
• If you need to pass caller/summary data, confirm how your carrier expects it (URI params, UUI, attributes mapped to headers).
If you want, paste these three items and I’ll review them and give the exact code edits:
• The identity of the SIP participant you intend to transfer (obfuscate sensitive parts).
• The log lines showing the participant join and the lines immediately before transfer.
• How you build the final transfer_to value (so I can suggest URI parameter encoding if needed).
I can then point out the exact line in your flow where the participant becomes unavailable or suggest a small code change to make the transfer call safe from race conditions.
Sources: Pass UUI data to Genesys Cloud during SIP transfers | LiveKit | Agents telephony integration | LiveKit Documentation | How to do call transfers with Five9 | LiveKit | Preserve caller ID during SIP transfers with Twilio | LiveKit