{"id":"677869483f33b176","repo":"gofiber/fiber","slug":"failed-to-write-cached-response-while-locked-w","errorCode":null,"errorMessage":"failed to write cached response while locked: %w","messagePattern":"failed to write cached response while locked: %w","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/idempotency/idempotency.go","lineNumber":136,"sourceCode":"\t\t// First-pass: if the idempotency key is in the storage, get and return the response\n\t\tif ok, err := maybeWriteCachedResponse(c, key); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to write cached response at fastpath: %w\", err)\n\t\t} else if ok {\n\t\t\treturn nil\n\t\t}\n\n\t\tif err := cfg.Lock.Lock(key); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to lock: %w\", err)\n\t\t}\n\t\tdefer func() {\n\t\t\tif err := cfg.Lock.Unlock(key); err != nil {\n\t\t\t\tlog.Errorf(\"[IDEMPOTENCY] failed to unlock key %q: %v\", maskKey(key), err)\n\t\t\t}\n\t\t}()\n\n\t\t// Lock acquired. If the idempotency key now is in the storage, get and return the response\n\t\tif ok, err := maybeWriteCachedResponse(c, key); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to write cached response while locked: %w\", err)\n\t\t} else if ok {\n\t\t\treturn nil\n\t\t}\n\n\t\t// Execute the request handler\n\t\tif err := c.Next(); err != nil {\n\t\t\t// If the request handler returned an error, return it and skip idempotency\n\t\t\treturn err\n\t\t}\n\n\t\t// Construct response\n\t\tres := &response{\n\t\t\tStatusCode: c.Response().StatusCode(),\n\t\t\tBody:       c.Response().Body(),\n\t\t}\n\t\t{\n\t\t\theaders := make(map[string][]string)\n\t\t\tif err := c.Bind().RespHeader(headers); err != nil {","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/gofiber/fiber/blob/9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c/middleware/idempotency/idempotency.go#L118-L154","documentation":"Wrapping error returned by the middleware (idempotency.go:135-136) when the SECOND maybeWriteCachedResponse call — performed AFTER acquiring Lock(key) — fails. Same underlying causes as [167] (read) and [168] (unmarshal), but the 'while locked' label indicates another request may currently hold or have just released the same key.","triggerScenarios":"Storage read or unmarshal failure after lock acquisition: typically a transient storage error coinciding with contention on the same idempotency key, or another writer having stored a corrupt payload between your fastpath check and your locked check.","commonSituations":"Two retries for the same key racing; another instance wrote a corrupt payload (see [168]); storage degraded under load.","solutions":["Unwrap to find the underlying read ([167]) or unmarshal ([168]) cause and apply those fixes.","Ensure the Storage is healthy under concurrent access — the locked re-read amplifies load.","Investigate key collisions if unmarshal failures cluster here."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"// same fail-open pattern as fastpath failures\nif err := mw(c); err != nil {\n    log.Printf(\"idempotency locked read failed: %v\", err)\n    return c.Next()\n}","preventionTips":["Investigate key collisions if [168]-class unmarshal failures cluster here.","Ensure Storage can sustain the post-lock re-read under contention.","Unwrap to classify the underlying read or unmarshal cause."],"tags":["idempotency","storage","lock","wrapper"],"analyzedSha":"9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c","analyzedAt":"2026-08-04T21:44:03.395Z","schemaVersion":2}