livekit/livekit · error

missing or unsupported action

Error message

missing or unsupported action

What it means

UpdateSIPInboundTrunk requires an Action oneof in the request describing how to modify the trunk. If req.Action is nil or an unimplemented oneof case, the switch falls to default and returns this error.

Source

Thrown at pkg/service/sip.go:213

		return nil, twirp.WrapError(twirp.NewError(twirp.InvalidArgument, err.Error()), err)
	}

	AppendLogFields(ctx,
		"request", logger.Proto(req),
		"trunkID", req.SipTrunkId,
	)

	// Validate all trunks including the new one first.
	info, err := s.store.LoadSIPInboundTrunk(ctx, req.SipTrunkId)
	if err != nil {
		if errors.Is(err, ErrSIPTrunkNotFound) {
			return nil, twirp.NewError(twirp.NotFound, err.Error())
		}
		return nil, err
	}
	switch a := req.Action.(type) {
	default:
		return nil, errors.New("missing or unsupported action")
	case livekit.UpdateSIPInboundTrunkRequestAction:
		var result livekit.ValidationResult
		info, result = a.ApplyResult(info)
		if err := result.LogUnlikelySoftErrors(unlikelyLoggerFromCtx(ctx)); err != nil {
			return nil, err
		}
	}

	it, err := ListSIPInboundTrunk(ctx, s.store, &livekit.ListSIPInboundTrunkRequest{
		Numbers: info.Numbers,
	})
	if err != nil {
		return nil, err
	}
	defer it.Close()
	if err = sip.ValidateTrunksIter(it, sip.WithTrunkReplace(func(t *livekit.SIPInboundTrunkInfo) *livekit.SIPInboundTrunkInfo {
		if req.SipTrunkId == t.SipTrunkId {
			return info // updated one

View on GitHub (pinned to ee45c3f0b1)

Solutions

  1. Set an action on the request, e.g. &livekit.UpdateSIPInboundTrunkRequest{SipId: id, Action: &livekit.UpdateSIPInboundTrunkRequest_SetName{...}}
  2. Regenerate/upgrade the livekit protocol package so client and server oneof cases match
  3. Verify with a debugger or proto dump that req.Action is non-nil

Example fix

// before
req := &livekit.UpdateSIPInboundTrunkRequest{SipId: trunkID}
// after
req := &livekit.UpdateSIPInboundTrunkRequest{SipId: trunkID,
    Action: &livekit.UpdateSIPInboundTrunkRequest_SetName{Name: "new-name"}}
Defensive patterns

Strategy: validation

Validate before calling

if req.Action == nil {
    return errors.New("UpdateSIPInboundTrunk requires an action")
}

Type guard

func validInboundTrunkAction(a isUpdateSIPInboundTrunkRequest_Action) bool {
    switch a.(type) {
    case *livekit.UpdateSIPInboundTrunkRequest_SetName, *livekit.UpdateSIPInboundTrunkRequest_SetMetadata, *livekit.UpdateSIPInboundTrunkRequest_AddNumbers, *livekit.UpdateSIPInboundTrunkRequest_RemoveNumbers:
        return true
    }
    return false
}

Prevention

When it happens

Trigger: Calling UpdateSIPInboundTrunk with a request that has no action set (e.g. livekit.UpdateSIPInboundTrunkRequest{} without setting one of the action fields); passing an action type the installed proto version doesn't know.

Common situations: Building the request struct in Go without populating the oneof; SDK/server version skew where the client sends a newer action type the server cannot handle; copy-pasted request from Create missing the action.

Related errors


AI-assisted analysis of livekit/livekit@ee45c3f0b1 (2026-09-02). Data as JSON: /api/errors/595f619912fccce5. Report an issue: GitHub.