{"record":{"id":"eb3c6a8550d45ded","repo":"gofiber/fiber","slug":"fiber-failed-to-s-shared-state-s-value-w","errorCode":null,"errorMessage":"fiber: failed to %s shared state %s value: %w","messagePattern":"fiber: failed to (.+?) shared state (.+?) value: %w","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shared_state.go","lineNumber":410,"sourceCode":"\t}()\n\n\tif recovered != nil {\n\t\treturn sharedStateCodecPanicError(\"decode\", format, recovered)\n\t}\n\tif err != nil {\n\t\treturn fmt.Errorf(\"fiber: failed to decode shared state %s value: %w\", format, err)\n\t}\n\n\treturn nil\n}\n\nfunc sharedStateCodecNotConfiguredError(format, direction string) error {\n\treturn fmt.Errorf(\"fiber: shared state %s %s is not configured\", format, direction)\n}\n\nfunc sharedStateCodecPanicError(operation, format string, recovered any) error {\n\tif err, ok := recovered.(error); ok {\n\t\treturn fmt.Errorf(\"fiber: failed to %s shared state %s value: %w\", operation, format, err)\n\t}\n\n\treturn fmt.Errorf(\"fiber: failed to %s shared state %s value: %v\", operation, format, recovered)\n}\n\nfunc (s *SharedState) storageKey(key string) (string, bool) {\n\tif key == \"\" {\n\t\treturn \"\", false\n\t}\n\n\treturn s.prefix + hex.EncodeToString(utils.UnsafeBytes(key)), true\n}\n","sourceCodeStart":392,"sourceCodeEnd":423,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/shared_state.go#L392-L423","documentation":"Thrown by sharedStateCodecPanicError when a user-configured codec (encoder/decoder for SharedState, e.g. JSON, Msgpack) panics while serializing/deserializing a shared-state value, and the recovered panic value implements error. Fiber wraps the original error so the caller can see both the operation (encode/decode), the format, and the root cause. It surfaces only when Config app/shared-state serialization is in use and the codec itself is buggy or receives a non-serializable value.","triggerScenarios":"A SharedState codec (set via app config) panics during Acquire/Release of a state value; the panic value is an error type. This happens inside the recover() block of the encode/decode wrapper, so it appears as a returned error from the state operation rather than a crash.","commonSituations":"Registering a custom codec that calls json.Marshal on a value containing a channel/func; msgp-generated codec fed a type it was not generated for; version mismatch where the codec library changed its error type; passing a non-serializable struct into ctx.Locals or shared state.","solutions":["Inspect the wrapped error (%w) to identify the underlying codec failure and fix the value or the codec.","Ensure every value stored in SharedState is of a type your configured codec can round-trip (e.g. plain structs/maps for JSON, msgp-generated types for msgp).","If using a custom codec, audit its encode/decode for panics on edge-case inputs and return errors instead of panicking.","Add a unit test that encodes then decodes each value type you intend to store, to catch regressions before runtime."],"exampleFix":"// before: storing a value the codec cannot serialize\napp.State().Set(\"conn\", liveDBConn)\n\n// after: store only serializable descriptors\napp.State().Set(\"connInfo\", map[string]string{\"dsn\": dsn})","handlingStrategy":"try-catch","validationCode":"// Verify each value is round-trippable before storing it\nfunc safeSet(state *fiber.SharedState, key string, val any, codec Codec) error {\n    b, err := codec.Encode(val)\n    if err != nil { return fmt.Errorf(\"encode %s: %w\", key, err) }\n    var back any\n    if err := codec.Decode(b, &back); err != nil { return fmt.Errorf(\"decode %s: %w\", key, err) }\n    state.Set(key, val)\n    return nil\n}","typeGuard":"// Reject values known to be non-serializable before they reach SharedState\nfunc isSerializable(v any) bool {\n    rv := reflect.ValueOf(v)\n    switch rv.Kind() {\n    case reflect.Chan, reflect.Func, reflect.Invalid:\n        return false\n    }\n    return true\n}","tryCatchPattern":"// Wrap state operations that go through a user codec\nfunc safeDecode(codec Codec, b []byte, dst any) (err error) {\n    defer func() {\n        if r := recover(); r != nil {\n            err = fmt.Errorf(\"codec panic: %v\", r)\n        }\n    }()\n    return codec.Decode(b, dst)\n}","preventionTips":["Keep a whitelist of value types allowed in SharedState and enforce it in a wrapper.","Audit custom codecs for panic paths and convert them to returned errors.","Add a round-trip property test for each codec/value-type pair."],"tags":["shared-state","codec","serialization","panic-recovery"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}