{"record":{"id":"4ca8da2f933113f5","repo":"beego/beego","slug":"colon-1-method-doesn-t-exist-in-the-controlle","errorCode":null,"errorMessage":"'{colon[1]}' method doesn't exist in the controller {t.Name()}","messagePattern":"'(.+?)' method doesn't exist in the controller (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"server/web/router.go","lineNumber":253,"sourceCode":"\t\treturn methods\n\t}\n\n\tsemi := strings.Split(mappingMethods[0], \";\")\n\tfor _, v := range semi {\n\t\tcolon := strings.Split(v, \":\")\n\t\tif len(colon) != 2 {\n\t\t\tpanic(\"method mapping format is invalid\")\n\t\t}\n\t\tcomma := strings.Split(colon[0], \",\")\n\t\tfor _, m := range comma {\n\t\t\tif m != \"*\" && !HTTPMETHOD[strings.ToUpper(m)] {\n\t\t\t\tpanic(v + \" is an invalid method mapping. Method doesn't exist \" + m)\n\t\t\t}\n\t\t\tif val := reflectVal.MethodByName(colon[1]); val.IsValid() {\n\t\t\t\tmethods[strings.ToUpper(m)] = colon[1]\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tpanic(\"'\" + colon[1] + \"' method doesn't exist in the controller \" + t.Name())\n\t\t}\n\t}\n\n\treturn methods\n}\n\nfunc (p *ControllerRegister) addRouterForMethod(route *ControllerInfo) {\n\tif len(route.methods) == 0 {\n\t\tfor m := range HTTPMETHOD {\n\t\t\tp.addToRouter(m, route.pattern, route)\n\t\t}\n\t\treturn\n\t}\n\tfor k := range route.methods {\n\t\tif k != \"*\" {\n\t\t\tp.addToRouter(k, route.pattern, route)\n\t\t\tcontinue\n\t\t}","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/beego/beego/blob/939cfde380bb9f15844ad633b84f037f7da21584/server/web/router.go#L235-L271","documentation":"server/web/router.go:253: parseMappingMethods panics when the controller-side method name in a mapping segment does not resolve on the controller. After validating the HTTP method token, the router does reflectVal.MethodByName(colon[1]) on the controller value passed to web.Router; if the method does not exist (or is unexported, which MethodByName will not find), registration panics with \"'{name}' method doesn't exist in the controller {Type}\". The lookup is exact and case-sensitive.","triggerScenarios":"web.Router(\"/api\", &ApiController{}, \"get:Lists\") where the controller defines List, not Lists. Also mapping to an unexported method like \"get:list\" (reflection skips lowercase names), or renaming a controller method without updating the routing string.","commonSituations":"Rename refactors that miss the mapping string; plural/singular or case mismatches between route config and controller methods; mapping to methods defined on an embedded controller from another package that was refactored during a beego upgrade; generated routers referencing deleted handlers.","solutions":["Match the mapping name exactly to an exported method on the controller: \"get:List\" requires func (c *ApiController) List().","Export the method (capitalize first letter) — unexported methods can never be mapped.","After refactors, grep the mapping strings for the old method name or compile a smoke test that registers all routes at startup.","Validate candidate mappings against reflect.ValueOf(c).MethodByName(name) before calling web.Router (see validationCode)."],"exampleFix":"// before\ntype ApiController struct{ web.Controller }\nfunc (c *ApiController) List() { /* ... */ }\nweb.Router(\"/api\", &ApiController{}, \"get:Lists\") // panic: Lists doesn't exist\n\n// after\nweb.Router(\"/api\", &ApiController{}, \"get:List\")","handlingStrategy":"validation","validationCode":"// Verify each mapped controller method exists and is exported before web.Router\nfunc mappingTargetsExist(c web.ControllerInterface, s string) error {\n    v := reflect.ValueOf(c)\n    for _, seg := range strings.Split(s, \";\") {\n        parts := strings.Split(seg, \":\")\n        if len(parts) != 2 {\n            continue // format errors are handled by validation for error 275\n        }\n        name := parts[1]\n        if !v.MethodByName(name).IsValid() {\n            return fmt.Errorf(\"controller %T has no exported method %q\", c, name)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"Go: validate before registration; if routes come from generated code, recover during registration and report the controller/method pair: defer func() { if r := recover(); r != nil { log.Fatalf(\"route for %T rejected: %v\", c, r) } }()","preventionTips":["Keep mapping strings adjacent to the controller methods they name and rename both together.","Only exported methods can be mapped — capitalize the first letter.","Add a startup route-registration smoke test to every service."],"tags":["go","beego","router","panic","reflection","controller","routing"],"backgroundTag":null,"analyzedSha":"939cfde380bb9f15844ad633b84f037f7da21584","analyzedAt":"2026-08-15T17:22:06.535Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}