{"record":{"id":"595f619912fccce5","repo":"livekit/livekit","slug":"missing-or-unsupported-action","errorCode":null,"errorMessage":"missing or unsupported action","messagePattern":"missing or unsupported action","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/service/sip.go","lineNumber":213,"sourceCode":"\t\treturn nil, twirp.WrapError(twirp.NewError(twirp.InvalidArgument, err.Error()), err)\n\t}\n\n\tAppendLogFields(ctx,\n\t\t\"request\", logger.Proto(req),\n\t\t\"trunkID\", req.SipTrunkId,\n\t)\n\n\t// Validate all trunks including the new one first.\n\tinfo, err := s.store.LoadSIPInboundTrunk(ctx, req.SipTrunkId)\n\tif err != nil {\n\t\tif errors.Is(err, ErrSIPTrunkNotFound) {\n\t\t\treturn nil, twirp.NewError(twirp.NotFound, err.Error())\n\t\t}\n\t\treturn nil, err\n\t}\n\tswitch a := req.Action.(type) {\n\tdefault:\n\t\treturn nil, errors.New(\"missing or unsupported action\")\n\tcase livekit.UpdateSIPInboundTrunkRequestAction:\n\t\tvar result livekit.ValidationResult\n\t\tinfo, result = a.ApplyResult(info)\n\t\tif err := result.LogUnlikelySoftErrors(unlikelyLoggerFromCtx(ctx)); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t}\n\n\tit, err := ListSIPInboundTrunk(ctx, s.store, &livekit.ListSIPInboundTrunkRequest{\n\t\tNumbers: info.Numbers,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer it.Close()\n\tif err = sip.ValidateTrunksIter(it, sip.WithTrunkReplace(func(t *livekit.SIPInboundTrunkInfo) *livekit.SIPInboundTrunkInfo {\n\t\tif req.SipTrunkId == t.SipTrunkId {\n\t\t\treturn info // updated one","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/livekit/livekit/blob/ee45c3f0b1a83bf4352dbccb6607ebf70b2a5de6/pkg/service/sip.go#L195-L231","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set an action on the request, e.g. &livekit.UpdateSIPInboundTrunkRequest{SipId: id, Action: &livekit.UpdateSIPInboundTrunkRequest_SetName{...}}","Regenerate/upgrade the livekit protocol package so client and server oneof cases match","Verify with a debugger or proto dump that req.Action is non-nil"],"exampleFix":"// before\nreq := &livekit.UpdateSIPInboundTrunkRequest{SipId: trunkID}\n// after\nreq := &livekit.UpdateSIPInboundTrunkRequest{SipId: trunkID,\n    Action: &livekit.UpdateSIPInboundTrunkRequest_SetName{Name: \"new-name\"}}","handlingStrategy":"validation","validationCode":"if req.Action == nil {\n    return errors.New(\"UpdateSIPInboundTrunk requires an action\")\n}","typeGuard":"func validInboundTrunkAction(a isUpdateSIPInboundTrunkRequest_Action) bool {\n    switch a.(type) {\n    case *livekit.UpdateSIPInboundTrunkRequest_SetName, *livekit.UpdateSIPInboundTrunkRequest_SetMetadata, *livekit.UpdateSIPInboundTrunkRequest_AddNumbers, *livekit.UpdateSIPInboundTrunkRequest_RemoveNumbers:\n        return true\n    }\n    return false\n}","tryCatchPattern":null,"preventionTips":["Use generated New... constructors or helper builders that set an action","Keep protocol bindings in lockstep with the server version","Add a unit test asserting every update request built by your code sets Action"],"tags":["sip","validation","grpc"],"backgroundTag":"missing-request-action","analyzedSha":"ee45c3f0b1a83bf4352dbccb6607ebf70b2a5de6","analyzedAt":"2026-09-02T03:56:08.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}