{"record":{"id":"5f4730f08a543fdf","repo":"kataras/iris","slug":"mvc-dependenciesreadonly-called-from-wrong-state","errorCode":null,"errorMessage":"MVC: DependenciesReadOnly called from wrong state the API gives access to it only `AfterActivation`, report this as bug","messagePattern":"MVC: DependenciesReadOnly called from wrong state the API gives access to it only `AfterActivation`, report this as bug","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mvc/controller.go","lineNumber":331,"sourceCode":"\treturn c\n}\n\n// Singleton returns new if all incoming clients' requests\n// have the same controller instance.\n// This is done automatically by iris to reduce the creation\n// of a new controller on each request, if the controller doesn't contain\n// any unexported fields and all fields are services-like, static.\nfunc (c *ControllerActivator) Singleton() bool {\n\tif c.injector == nil {\n\t\tpanic(\"MVC: Singleton called from wrong state the API gives access to it only `AfterActivation`, report this as bug\")\n\t}\n\treturn c.injector.Singleton\n}\n\n// DependenciesReadOnly returns a list of dependencies, including the controller's one.\nfunc (c *ControllerActivator) DependenciesReadOnly() []*hero.Dependency {\n\tif c.injector == nil {\n\t\tpanic(\"MVC: DependenciesReadOnly called from wrong state the API gives access to it only `AfterActivation`, report this as bug\")\n\t}\n\n\treturn c.injector.Container.Dependencies\n}\n\n// Dependencies returns a value which can manage the controller's dependencies.\nfunc (c *ControllerActivator) Dependencies() *hero.Container {\n\treturn c.app.container // although the controller's one are: c.injector.Container\n}\n\n// checks if a method is already registered.\nfunc (c *ControllerActivator) isReservedMethod(name string) bool {\n\tfor methodName := range c.routes {\n\t\tif methodName == name {\n\t\t\treturn true\n\t\t}\n\t}\n","sourceCodeStart":313,"sourceCodeEnd":349,"githubUrl":"https://github.com/kataras/iris/blob/7bedaf55a0b64bbb2248a5845a2c60d81a30996a/mvc/controller.go#L313-L349","documentation":"DependenciesReadOnly returns the controller's resolved dependency list from the injector container, which does not exist until the controller is activated. Calling it before activation means the dependency-injection graph has not been built, so it panics to expose the illegal state instead of returning nil.","triggerScenarios":"Calling activator.DependenciesReadOnly() before mvc activation completes — e.g. in Configure hooks, right after Handle(), or in a test before AfterActivation ran.","commonSituations":"Introspection/debug tooling that walks registered controllers at boot, dependency audit code, or documentation examples copied out of the AfterActivation context.","solutions":["Query DependenciesReadOnly only from an AfterActivation callback where the injector is guaranteed to exist.","If you must know dependencies earlier, collect them from the hero.Container you registered rather than the activator.","Report as a bug if the panic occurs inside AfterActivation despite correct usage."],"exampleFix":"// before\ndeps := m.Activator.DependenciesReadOnly() // panics before activation\n// after\nm.AfterActivation(func(a *mvc.Activation) {\n\tdeps := a.DependenciesReadOnly()\n\tfor _, d := range deps { log.Println(d.DestType) }\n})","handlingStrategy":"validation","validationCode":"mvcApp.AfterActivation(func(a *mvc.Activation) {\n\tfor _, d := range a.DependenciesReadOnly() {\n\t\tlog.Printf(\"dep: %v\", d.DestType)\n\t}\n})","typeGuard":null,"tryCatchPattern":"defer func() {\n\tif r := recover(); r != nil {\n\t\tlog.Printf(\"DependenciesReadOnly before activation: %v\", r)\n\t}\n}()","preventionTips":["Never query activator state during Configure or before Handle completes.","Centralize MVC introspection in AfterActivation callbacks.","Derive dependency info from your hero.Container registration instead."],"tags":["panic","mvc","dependency-injection","lifecycle"],"backgroundTag":"api-called-before-initialized","analyzedSha":"7bedaf55a0b64bbb2248a5845a2c60d81a30996a","analyzedAt":"2026-08-30T20:38:16.250Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}