{"record":{"id":"ae22d5bde54d2c44","repo":"kataras/iris","slug":"binder-singleton-setting-is-set-to-true-but-struc","errorCode":null,"errorMessage":"binder: Singleton setting is set to true but struct has dynamic bindings: %s","messagePattern":"binder: Singleton setting is set to true but struct has dynamic bindings: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"hero/struct.go","lineNumber":109,"sourceCode":"\t\t\t\tif err == ErrSeeOther {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tpanic(err)\n\t\t\t}\n\n\t\t\telem.FieldByIndex(b.Input.StructFieldIndex).Set(input)\n\t\t} else if !b.Dependency.Static {\n\t\t\tif disableStructDynamicBindings {\n\t\t\t\tpanic(fmt.Sprintf(\"binder: DisableStructDynamicBindings setting is set to true: dynamic binding found: %s\", b.String()))\n\t\t\t}\n\n\t\t\tsingleton = false\n\t\t}\n\t}\n\n\tif isSingleton && !singleton {\n\t\tpanic(fmt.Sprintf(\"binder: Singleton setting is set to true but struct has dynamic bindings: %s\", typ))\n\t}\n\n\ts := &Struct{\n\t\tptrValue:    v,\n\t\tptrType:     typ,\n\t\telementType: elem.Type(),\n\t\tbindings:    bindings,\n\t\tSingleton:   singleton,\n\t}\n\n\tisErrHandler := isErrorHandler(typ)\n\tnewContainer := c.Clone()\n\tnewContainer.fillReport(typ.String(), bindings)\n\t// Add the controller dependency itself as func dependency but with a known type which should be explicit binding\n\t// in order to keep its maximum priority.\n\tnewContainer.Register(s.Acquire).Explicitly().DestType = typ\n\n\tnewContainer.GetErrorHandler = func(ctx *context.Context) ErrorHandler {","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/kataras/iris/blob/7bedaf55a0b64bbb2248a5845a2c60d81a30996a/hero/struct.go#L91-L127","documentation":"The hero dependency-injection binder panics when a struct is registered with Singleton lifetime but its fields use dynamic bindings (bindings that can produce different values per resolution, such as non-singleton dependencies). A singleton cannot be safely cached if its contents depend on per-request bindings, so the library refuses the combination at registration time (hero/struct.go:109, in makeStruct).","triggerScenarios":"Calling Struct(...) (via hero.New / hero.Struct) on a type marked as singleton whose exported fields are bound with dynamic bindings — e.g. bindings created from non-singleton dependency functions or explicit Binding values that are not static.","commonSituations":"Developers register a controller struct with .Singleton() (or use default singleton behavior) while one of its fields is a type bound dynamically, often after adding a new field with a request-scoped dependency like *context.Context or a per-request service.","solutions":["Make the struct non-singleton (remove Singleton() or set it to false) so it is built per request.","Change the dynamic bindings used by the struct's fields to singleton/static bindings so the struct can be safely cached.","Move the dynamic dependency out of the struct fields and resolve it inside handler method parameters instead.","Restructure so the singleton struct holds only immutable/static dependencies and wrap dynamic state in a separate request-scoped service."],"exampleFix":"// before\nbinder := hero.New(hero.Struct(MyController{}, true /* singleton */))\n// MyController has a field of a dynamically-bound type\n\n// after\nbinder := hero.New(hero.Struct(MyController{}, false))\n// or: bind the field's type as a singleton too","handlingStrategy":"validation","validationCode":"// Before registering, ensure all field bindings are singleton/static\n// or register without singleton:\nbinder := hero.New()\nif usesDynamicBindings(MyController{}) {\n    binder.Register(MyController{}) // not singleton\n} else {\n    binder.Singleton = true\n    binder.Register(MyController{})\n}","typeGuard":null,"tryCatchPattern":"// Panics are not recoverable per-handler; run registration inside a guarded init:\nfunc initBinder() (b *hero.Binder) {\n    defer func() {\n        if r := recover(); r != nil {\n            log.Fatalf(\"binder config invalid: %v\", r)\n        }\n    }()\n    return hero.New(hero.Struct(MyController{}, true))\n}","preventionTips":["Only mark structs singleton when all their field dependencies are singletons too.","Resolve request-scoped dependencies via handler method parameters, not struct fields.","Cover binder registration in an init-time test to surface the panic at startup."],"tags":["go","dependency-injection","panic","singleton"],"backgroundTag":"singleton-with-dynamic-bindings","analyzedSha":"7bedaf55a0b64bbb2248a5845a2c60d81a30996a","analyzedAt":"2026-08-30T20:38:16.250Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}