Skip to content

Errors ​

Every failure in Beam carries a machine-readable reason beside its message, on both sides of the wire. Match on the reason; show the message.

PHP: BeamException ​

RealRashid\Beam\Exceptions\BeamException — $e->reason() is the string, $e->errorCode the ErrorCode enum.

ReasonThrown byMeans
FORBIDDENring(), $room->token(), the routesa gate refused, or a token was presented by the wrong user
EXPIREDToken::parse(), the routesthe token's expiresAt has passed
TAMPEREDToken::parse(), the routesthe token does not decrypt or verify
PROTOCOL_MISMATCHToken::parse()the token was minted by a different Beam version than the one reading it
NOT_FOUNDBeam::findOrFail(), Beam::room()->findOrFail(), POST /beam/transfersno such live call, room or user — find() returns null instead, as it does everywhere in Laravel
TURN_UNAVAILABLETURN driversthe vendor's API refused or timed out; TurnUnavailable fires and the call proceeds on STUN
INVALID_CONFIGURATIONbuilders, drivers, link()a room name, a driver key or a missing route
GATEWAY_ERRORHTTP TURN driversthe vendor answered with something that was not credentials
PUSH_UNAVAILABLEthe push routesWeb Push is not configured on this server
ROOM_FULL$room->token()two people are already in that room; a Beam room carries two

Thrown inside a request — a gate refusing ring() in your controller, say — a BeamException renders itself as JSON, {"message": "…", "reason": "…"}, with the status its reason implies: 403 for FORBIDDEN, 401 for EXPIRED, TAMPERED and PROTOCOL_MISMATCH, 404 for NOT_FOUND, 503 for TURN_UNAVAILABLE, GATEWAY_ERROR and PUSH_UNAVAILABLE. An INVALID_CONFIGURATION in a browser request gets Laravel's normal error page, because that one is for you.

HTTP responses ​

Beam's routes answer JSON: {"message": "…", "reason": "…"}.

StatusReasonWhen
401MISSING_TOKENno token on a route that needs one
401EXPIRED, TAMPERED, PROTOCOL_MISMATCHthe token failed to parse
403FORBIDDENthe token is another user's, names another channel, or the user is not a participant of that live call
404NOT_FOUNDthe call, room or user does not exist
409ROOM_FULLa third person asked for a token to a room that already has two
413TOO_LARGEa file offer over transfer.max_bytes
422(validation)a malformed signal
503PUSH_UNAVAILABLEthe VAPID public key was asked for and there is none

JavaScript: BeamError ​

Beam.join() and the controls reject with, and call.on('error') receives, a BeamError with .reason and .message.

ReasonMeansUsually
permission-deniedthe camera, microphone, screen or notifications were refusedshow how to allow them; a call cannot start without media
no-deviceno camera or microphone was foundoffer audio-only
media-failedthe device could not be opened, or the page is not a secure contextcheck HTTPS; another app may hold the camera
screen-unavailablethis browser has no screen picker (Android, iOS) or the stream carried no videohide the share button — platform.supportsDisplayMedia()
protocol-mismatchthe token was minted by a different Beam version than the clienta cached beam.js; beam:doctor checks it
expiredthe token's time has passedfetch a fresh page
malformedthe token does not decodeit was edited or truncated
signaling-failedthe server refused a signal, or Echo is missingthe response's reason says which; Beam.configure({ echo })
turn-unavailablethe token carried no usable relaythe call may still connect on STUN
connection-failednegotiation failed, or a transfer's hash did not matchretry; report
declinedthe other side declined the call or the fileshow it
timeoutnobody answered in timeshow it
autoplay-blockedthe browser refused to play the remote stream without a tapsay "tap to hear"; Beam retries on the next tap
unsupportedthis browser lacks the feature (setSpeaker() on Safari)hide the control
room-fulla third participant is signalling on a room's channel; their messages are being ignoredsay the room is busy — your server refuses the third token, so this is the rare case of one already in flight

A call that ends carries a reason too, on the ended event and in CallEnded. Every one Beam itself uses:

ReasonWho ends it
hangupeither side called hangUp()
remote-hangupthe other side hung up and this browser heard the bye
navigatedthis browser left the page or unmounted the component
declinedthe callee declined the ring
timeoutnobody answered before timeout seconds
connection-lostrecovery ran out — the browser's own reconnect_timeout, or the server finding nothing has heartbeated for three intervals
server$call->end() on the server with no reason given
closed$room->close()

Anything else is a string your own code passed to end() or decline().


Made with ❤️ from Pakistan

Made with ❤️ from Pakistan · Released under the MIT License.