{"record":{"id":"c07068acb9e2ecd0","repo":"v2rayA/v2rayA","slug":"bad-request-unsupported-touch-type","errorCode":null,"errorMessage":"bad request: unsupported touch type","messagePattern":"bad request: unsupported touch type","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/server/service/import.go","lineNumber":70,"sourceCode":"\turlLower := strings.ToLower(url)\n\tif PluginManagerValidateLink(url) || common.HasAnyPrefix(urlLower, supportedPrefix) {\n\t\tlog.Trace(\"Import: url matches supported prefixes or is valid for PluginManager\")\n\t\tvar obj serverObj.ServerObj\n\t\tobj, err = ResolveURL(url)\n\t\tif err != nil {\n\t\t\tlog.Warn(\"ResolveURL failed: %v\", err)\n\t\t\treturn\n\t\t}\n\t\tif which != nil && which.ID > 0 {\n\t\t\t// the request is to modify a server\n\t\t\tind := which.ID - 1\n\t\t\tlog.Info(\"Import: modifying server. ind=%v, which.ID=%v, which.TYPE=%v\", ind, which.ID, which.TYPE)\n\t\t\tif which.TYPE != configure.ServerType {\n\t\t\t\t// Also support modifying subscription servers if the frontend allows it\n\t\t\t\t// but for now, we primarily care about ServerType\n\t\t\t\tif which.TYPE != configure.SubscriptionServerType {\n\t\t\t\t\tlog.Warn(\"Import: unsupported touch type for modification: %v\", which.TYPE)\n\t\t\t\t\treturn fmt.Errorf(\"bad request: unsupported touch type\")\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif which.TYPE == configure.ServerType && (ind < 0 || ind >= configure.GetLenServers()) {\n\t\t\t\tlog.Warn(\"Import: invalid server index: %v\", ind)\n\t\t\t\treturn fmt.Errorf(\"bad request: invalid index\")\n\t\t\t}\n\n\t\t\tif err = configure.SetServer(ind, &configure.ServerRaw{ServerObj: obj}); err != nil {\n\t\t\t\tlog.Warn(\"Import: SetServer failed: %v\", err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tlog.Info(\"Import: SetServer success for index %v\", ind)\n\t\t\tcss := configure.GetConnectedServers()\n\t\t\tif css.Len() > 0 {\n\t\t\t\tfor _, cs := range css.Get() {\n\t\t\t\t\tif which.TYPE == cs.TYPE && which.ID == cs.ID {\n\t\t\t\t\t\tlog.Info(\"Import: updating connected v2ray config\")","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/v2rayA/v2rayA/blob/71e5442fc548c05680ee55eae943e6c0afe9ac51/service/server/service/import.go#L52-L88","documentation":"Import() validates the TYPE of the target (server/subscription) before modifying it. If which.TYPE is neither configure.ServerType nor configure.SubscriptionServerType, modification is refused with this bad-request error. It is an input-validation guard against modifying entities the import API does not support.","triggerScenarios":"Calling Import (via initConfigure or the PostImport API) with a Which struct whose TYPE field is an unsupported value, e.g. SubscriptionType or a zero/unset TYPE, instead of ServerType or SubscriptionServerType.","commonSituations":"Frontend bugs sending the wrong touch type; API clients hand-crafting import requests and forgetting to set TYPE; schema/version changes where new TYPE values were added but Import was not updated.","solutions":["Set which.TYPE to configure.ServerType (or SubscriptionServerType) before calling Import","If importing into an existing server, fetch the target via configure and copy its TYPE rather than constructing one manually","Fix the frontend/API client to send the correct touch type field"],"exampleFix":"// before\nwhich := configure.Which{ID: 1, TYPE: configure.SubscriptionType}\nerr := service.Import(which, 0, obj)\n// after\nwhich := configure.Which{ID: 1, TYPE: configure.ServerType}\nerr := service.Import(which, 0, obj)","handlingStrategy":"validation","validationCode":"func validTouchType(t configure.TouchType) bool {\n    return t == configure.ServerType || t == configure.SubscriptionServerType\n}\nif !validTouchType(which.TYPE) {\n    return fmt.Errorf(\"refusing to import: unsupported touch type %v\", which.TYPE)\n}","typeGuard":"func isServerOrSubServer(w configure.Which) bool {\n    return w.TYPE == configure.ServerType || w.TYPE == configure.SubscriptionServerType\n}","tryCatchPattern":null,"preventionTips":["Always set TYPE explicitly when constructing Which structs","Copy TYPE from an existing configured entity when modifying it","Re-check client payloads after adding new TouchType values"],"tags":["validation","bad-request","input"],"backgroundTag":"unsupported-touch-type","analyzedSha":"71e5442fc548c05680ee55eae943e6c0afe9ac51","analyzedAt":"2026-09-05T20:04:37.459Z","contentChangedAt":"2026-09-05T20:04:37.459Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}