Skip to content

Update to v3#1391

Merged
ReneWerner87 merged 34 commits into
mainfrom
v3-beta
Sep 1, 2025
Merged

Update to v3#1391
ReneWerner87 merged 34 commits into
mainfrom
v3-beta

Conversation

@ReneWerner87
Copy link
Copy Markdown
Member

@ReneWerner87 ReneWerner87 commented Sep 1, 2025

Summary by CodeRabbit

  • New Features

    • Added helpers to retrieve request-scoped data: jwtware.FromContext and pasetoware.FromContext.
  • Refactor

    • Migrated all middlewares to Fiber v3 with value-based fiber.Ctx.
    • Updated handler and config callback signatures across packages (e.g., auth, logging, tracing, websockets).
    • Removed context-key fields in JWT and PASETO; tokens/payloads are stored internally.
    • Adjusted related utilities and helpers to the new APIs.
  • Documentation

    • Updated examples and install instructions for Fiber v3.
    • Raised minimum Go version to 1.25+ across docs.
  • Chores

    • Added a parallel test runner script to speed up module test execution.

sixcolors and others added 30 commits January 2, 2024 16:06
v3: Update Websocket to Fiber v3
chore: upgrade Fiber framework from v2 to v3
…h-RequestCtx

Correct fasthttp context with c.RequestCtx()
# Conflicts:
#	jwt/go.mod
#	jwt/go.sum
#	jwt/utils.go
#	websocket/go.mod
#	websocket/go.sum
git checkout main -- . ':!.github' ':!*.md'

find . -name go.mod -execdir sh -c 'echo "=== $(pwd) ==="; fiber migrate --to v3.0.0-beta.5 -f --hash="323d2c85c4a1e9444802c4253f5cb784a61290df"' \;
git checkout main -- . ':!.github' ':!*.md'

find . -name go.mod -execdir sh -c 'echo "=== $(pwd) ==="; fiber migrate --to v3.0.0-beta.5 -f --hash="323d2c85c4a1e9444802c4253f5cb784a61290df"' \;
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
sixcolors and others added 4 commits August 31, 2025 00:04
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
@ReneWerner87 ReneWerner87 added this to v3 Sep 1, 2025
@ReneWerner87 ReneWerner87 requested a review from a team as a code owner September 1, 2025 06:37
@ReneWerner87 ReneWerner87 added the v3 label Sep 1, 2025
@ReneWerner87 ReneWerner87 requested review from efectn, gaby and sixcolors and removed request for a team September 1, 2025 06:37
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Sep 1, 2025

Walkthrough

Project-wide migration from Fiber v2 to v3: updates imports, handler/context signatures (from *fiber.Ctx to fiber.Ctx), test harness (App.Test uses fiber.TestConfig), and logging/tracing integrations. JWT and PASETO middlewares remove ContextKey and add FromContext helpers. WebSocket, OTel, and various contrib middlewares adjust configs/callbacks. Adds a parallel Go test runner script.

Changes

Cohort / File(s) Summary
CI: Parallel Go Tests
.github/scripts/parallel-go-test.sh
New script to discover modules and run tests in parallel per module; prefers gotestsum; optional module prep (-m); centralized annotated error log; signal handling and cleanup.
Casbin (Fiber v3 + Ctx by value)
casbin/README.md, casbin/casbin.go, casbin/config.go, casbin/casbin_test.go
Migrate to fiber/v3; adjust handler and config callback signatures to fiber.Ctx (value); Config.Lookup type updated; docs updated.
Circuitbreaker (API callback types)
circuitbreaker/README.md, circuitbreaker/circuitbreaker.go, circuitbreaker/circuitbreaker_test.go
Switch to fiber/v3; Config.IsFailure/OnOpen/OnHalfOpen/OnClose now take fiber.Ctx (value); tests adapted.
fgprof (v3 + tests)
fgprof/README.md, fgprof/config.go, fgprof/fgprof.go, fgprof/fgprof_test.go
Upgrade to fiber/v3; Next func uses fiber.Ctx; handler uses fiber.Ctx; tests use testify and fiber.TestConfig.
fiberi18n (v3 + public funcs)
fiberi18n/README.md, fiberi18n/config.go, fiberi18n/i18n.go, fiberi18n/example/main.go, fiberi18n/embed_test.go, fiberi18n/i18n_test.go
Migrate to fiber/v3; Next/LangHandler and MustLocalize/Localize accept fiber.Ctx; tests and examples updated.
fibernewrelic (API and context access)
fibernewrelic/README.md, fibernewrelic/fiber.go, fibernewrelic/fiber_test.go
Move to fiber/v3; Config.Next/ErrorStatusCodeHandler now fiber.Ctx; FromContext(c fiber.Ctx) updated; RequestCtx-based access; tests updated with TestConfig.
fibersentry (v3 + helpers)
fibersentry/README.md, fibersentry/sentry.go, fibersentry/sentry_test.go
Switch to fiber/v3; middleware and helpers use fiber.Ctx; tests adapt handler signatures and App.Add API (methods slice).
fiberzap (logging generics + config callbacks)
fiberzap/README.md, fiberzap/config.go, fiberzap/logger.go, fiberzap/logger_test.go, fiberzap/zap.go, fiberzap/zap_test.go
Migrate to fiber/v3; Config callbacks now fiber.Ctx; AllLogger assertion updated to generic; SetLogger now generic; tests updated and use testify.
fiberzerolog (config callbacks + ctx)
fiberzerolog/README.md, fiberzerolog/config.go, fiberzerolog/zerolog.go, fiberzerolog/zerolog_test.go
Upgrade to fiber/v3; Config callbacks accept fiber.Ctx; middleware uses fiber.Ctx; tests update handlers, config funcs, and assertions.
hcaptcha (docs + test harness)
hcaptcha/README.md, hcaptcha/hcaptcha_test.go
Raise Go requirement; tests switch to fiber.TestConfig; import ordering.
JWT middleware (API reshape + FromContext)
jwt/README.md, jwt/config.go, jwt/jwt.go, jwt/utils.go, jwt/config_test.go, jwt/jwt_test.go
Migrate to fiber/v3; remove ContextKey; add internal tokenKey and public FromContext(c fiber.Ctx) *jwt.Token; Config.Filter/handlers use fiber.Ctx; extractors use fiber.Ctx; tests updated and expanded.
loadshed (callbacks value ctx + tests)
loadshed/README.md, loadshed/loadshed.go, loadshed/loadshed_test.go
Move to fiber/v3; Config.Next/OnShed use fiber.Ctx; RequestCtx usage; tests updated and use testify.
monitor (Next callback change + tests)
monitor/config.go, monitor/config_test.go, monitor/monitor_test.go
Config.Next now func(fiber.Ctx) bool; tests updated accordingly.
opafiber (InputCreationFunc change + tests)
opafiber/README.md, opafiber/fiber.go, opafiber/fiber_test.go
Switch to fiber/v3; InputCreationFunc now takes fiber.Ctx; handler uses fiber.Ctx; tests updated and App.Test uses TestConfig.
otelfiber (v3 tracing context changes)
otelfiber/README.md, otelfiber/config.go, otelfiber/fiber.go, otelfiber/semconv.go, otelfiber/example/server.go, otelfiber/otelfiber_test/...
Migrate to fiber/v3; all option callbacks use fiber.Ctx; internal tracing uses c/request context directly; remove SetUserContext usage; examples/tests updated; App.Test uses TestConfig.
PASETO middleware (ContextKey removal + FromContext)
paseto/README.md, paseto/config.go, paseto/helpers.go, paseto/paseto.go, paseto/config_test.go, paseto/paseto_test.go
Migrate to fiber/v3; remove Config.ContextKey; add unexported payloadKey and public FromContext(c fiber.Ctx) interface{}; Config.Next uses fiber.Ctx; helpers use fiber.Ctx; tests/docs updated.
socketio (middleware signature)
socketio/README.md, socketio/socketio.go, socketio/socketio_test.go
Switch to fiber/v3; New returns func(fiber.Ctx) error; tests update middleware signature and app config.
swagger (v3 + Next callback)
swagger/README.md, swagger/swagger.go, swagger/swagger_test.go
Upgrade to fiber/v3; Config.Next now func(fiber.Ctx) bool; handler uses fiber.Ctx; tests use TestConfig and handler signatures updated.
testcontainers (docs)
testcontainers/README.md
Raise min Go version in docs.
websocket (API: Filter/IsWebSocketUpgrade)
websocket/README.md, websocket/websocket.go, websocket/websocket_test.go
Migrate to fiber/v3; Config.Filter uses fiber.Ctx; IsWebSocketUpgrade(c fiber.Ctx) bool; RequestCtx-based access; tests adapt Listen(..., fiber.ListenConfig).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Client
  participant Fiber as Fiber App
  participant JWT as jwtware.Middleware
  participant Handler as Protected Handler

  Client->>Fiber: HTTP Request with Authorization
  Fiber->>JWT: Invoke middleware (c fiber.Ctx)
  JWT->>JWT: Extract token (header/query/param/cookie)
  alt token valid
    JWT->>Fiber: c.Locals(tokenKey, token)
    note right of JWT: New helper<br/>FromContext(c) reads token
    JWT->>Fiber: Next()
    Fiber->>Handler: Call handler (c)
    Handler->>Fiber: jwtware.FromContext(c)
    Fiber-->>Client: 2xx/handler response
  else invalid/missing
    JWT-->>Client: Error via ErrorHandler
  end
Loading
sequenceDiagram
  autonumber
  participant Client
  participant Fiber as Fiber App
  participant WS as websocket.Middleware
  participant Upgrader as Upgrader

  Client->>Fiber: HTTP GET /ws (Upgrade: websocket)
  Fiber->>WS: Invoke (c fiber.Ctx)
  WS->>WS: IsWebSocketUpgrade(c)
  alt Upgrade true
    WS->>Upgrader: Upgrade(c.RequestCtx())
    Upgrader-->>WS: Success
    WS-->>Client: 101 Switching Protocols
  else
    WS-->>Client: 426 Upgrade Required
  end
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Suggested labels

🧹 Updates

Suggested reviewers

  • gaby
  • sixcolors
  • efectn

Poem

A rabbit taps its tiny keys—
v2 to v3, we sail with ease.
Context by value, neat and clean,
FromContext finds the token’s sheen.
Tests run in parallel—away!
Logs and webs hum all the way.
Hop hop, ship day! 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch v3-beta

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @ReneWerner87, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request represents a substantial effort to migrate the entire suite of Fiber contrib modules to be fully compatible with Fiber v3. The changes aim to modernize the codebase, align with the latest Fiber API conventions, and ensure that these middleware and utilities can seamlessly integrate with new Fiber applications. This comprehensive update enhances the overall stability, maintainability, and future-readiness of the contrib ecosystem.

Highlights

  • Fiber v3 Upgrade: All contrib modules have been updated to ensure full compatibility with github.com/gofiber/fiber/v3. This includes significant changes to middleware handler signatures, now passing fiber.Ctx by value instead of by pointer, aligning with Fiber v3's API.
  • Go Version Bump: The minimum Go version requirement across all contrib modules has been raised to Go 1.25, ensuring compatibility with modern Go features and toolchains.
  • Improved Testing Infrastructure: A new parallel-go-test.sh script has been introduced to facilitate parallel testing of Go modules, enhancing the efficiency of development and CI/CD workflows. Test assertions have also been migrated to stretchr/testify/assert for consistency.
  • Dependency Modernization: All go.mod and go.sum files have been thoroughly updated to reflect the latest compatible versions of both direct and indirect dependencies, contributing to a more secure and up-to-date project.
  • Context Handling Refinements: Specific modules like fibernewrelic and paseto have seen updates to their context handling mechanisms, including the introduction of new helper functions like FromContext for more idiomatic access to request-scoped data.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex Review: Here are some suggestions.

Reply with @codex fix comments to fix any unresolved comments.

About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you open a pull request for review, mark a draft as ready, or comment "@codex review". If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex fix this CI failure" or "@codex address that feedback".

Comment thread otelfiber/fiber.go
Comment on lines 174 to 175
//Propagate tracing context as headers in outbound response
tracingHeaders := make(propagation.HeaderCarrier)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Propagation span never attached to fiber context

The middleware now creates ctx with tracer.Start, but the previous call to c.SetUserContext(ctx) was removed and nothing replaces it. As a result cfg.Propagators.Inject(c, tracingHeaders) uses the original request context, so the generated span isn’t propagated to downstream handlers or response headers. This breaks distributed tracing because oteltrace.SpanFromContext(c) after the middleware returns nil. Use the context returned from tracer.Start when injecting headers and expose it on the request (via the v3 equivalent of SetUserContext).

Useful? React with 👍 / 👎.

Comment thread fibernewrelic/fiber.go
Comment on lines 97 to +100
},
})

c.SetUserContext(newrelic.NewContext(c.UserContext(), txn))
// TODO: SetUserContext was removed, please migrate manually: c.SetUserContext(newrelic.NewContext(c, txn))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] New Relic transaction never stored on request context

After creating the New Relic transaction the middleware used to call c.SetUserContext(newrelic.NewContext(...)) so downstream code could retrieve the transaction via FromContext. The migration removed that call without providing an alternative, leaving the request context unmodified and FromContext returning nil. The transaction should be attached to the request context using the v3 replacement for SetUserContext so other middleware/handlers can record attributes and errors on the same transaction.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the repository to support Fiber v3. The changes are extensive, touching many modules to align with the new v3 API, including dependency updates and signature changes. A new parallel testing script has also been added. The migration seems mostly correct, but I've identified a few issues, primarily in documentation and a new script, that should be addressed to ensure clarity and correctness for users and contributors.

Comment thread jwt/README.md
Comment on lines +39 to +47
| Property | Type | Description | Default |
|:---------------|:--------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------------------------|
| Filter | `func(fiber.Ctx) bool` | Defines a function to skip middleware | `nil` |
| SuccessHandler | `func(fiber.Ctx) error` | SuccessHandler defines a function which is executed for a valid token. | `nil` |
| ErrorHandler | `func(fiber.Ctx, error) error` | ErrorHandler defines a function which is executed for an invalid token. | `401 Invalid or expired JWT` |
| SigningKey | `interface{}` | Signing key to validate token. Used as fallback if SigningKeys has length 0. | `nil` |
| SigningKeys | `map[string]interface{}` | Map of signing keys to validate token with kid field usage. | `nil` |
| Claims | `jwt.Claims` | Claims are extendable claims data defining token content. | `jwt.MapClaims{}` |
| TokenLookup | `string` | TokenLookup is a string in the form of `<source>:<name>` that is used | `
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The configuration table seems to be incomplete and malformed after the changes. Several important configuration options like AuthScheme, KeyFunc, and JWKSetURLs are missing, and the entry for TokenLookup is cut off. The previous, more detailed table should be restored and updated for v3.

if [ "$RUN_GOMOD" -eq 1 ]; then
local mod_step_log="$TMPDIR/$safe.modlog"
: > "$mod_step_log"
( cd "$module_dir" 2>/dev/null && go mod download >>"$mod_step_log" 2>&1 ) || true
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The redirection of stderr from cd to /dev/null (2>/dev/null) hides potentially useful error messages if the directory cannot be entered (e.g., due to permissions or it being removed). While the && ensures the subsequent command doesn't run in the wrong directory, obscuring the cd error makes debugging harder. It's better to remove 2>/dev/null to allow cd to report errors. This applies to similar constructs on lines 237 and 248 as well.

Suggested change
( cd "$module_dir" 2>/dev/null && go mod download >>"$mod_step_log" 2>&1 ) || true
( cd "$module_dir" && go mod download >>"$mod_step_log" 2>&1 ) || true

Comment thread fibernewrelic/fiber.go
})

c.SetUserContext(newrelic.NewContext(c.UserContext(), txn))
// TODO: SetUserContext was removed, please migrate manually: c.SetUserContext(newrelic.NewContext(c, txn))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This TODO comment is misleading as it suggests using c.SetUserContext, which has been removed in Fiber v3. Since the context can no longer be replaced for downstream handlers, the transaction won't be available via newrelic.FromContext(c). This is a significant breaking change that needs to be addressed, perhaps by using c.Locals or another mechanism to propagate the transaction.

Comment thread otelfiber/fiber.go

// pass the span through userContext
c.SetUserContext(ctx)
// TODO: SetUserContext was removed, please migrate manually: c.SetUserContext(ctx)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This TODO comment is misleading as it suggests using c.SetUserContext, which has been removed in Fiber v3. This is a significant breaking change. A more helpful comment would guide the user on how to adapt. For example, it could clarify that oteltrace.SpanFromContext(c) should be used by downstream handlers to access the span, as the context is no longer replaced. This also applies to the TODO on line 164.

@ReneWerner87 ReneWerner87 merged commit 0a0ce71 into main Sep 1, 2025
1 of 2 checks passed
@ReneWerner87 ReneWerner87 deleted the v3-beta branch September 1, 2025 06:44
@github-project-automation github-project-automation Bot moved this to Done in v3 Sep 1, 2025
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 30

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (46)
hcaptcha/hcaptcha_test.go (1)

35-39: Move defer res.Body.Close() after the error check to prevent nil dereference
In hcaptcha/hcaptcha_test.go, update:

-res, err := app.Test(req, fiber.TestConfig{Timeout: 0, FailOnTimeout: false})
-defer res.Body.Close()
-if err != nil {
-    t.Fatal(err)
-}
+res, err := app.Test(req, fiber.TestConfig{Timeout: 0, FailOnTimeout: false})
+if err != nil {
+    t.Fatal(err)
+}
+defer res.Body.Close()
fiberzerolog/README.md (2)

51-56: Example does not compile: missing os import and outdated handler signature.

  • Add os to imports (used at Line 59).
  • Switch handler to value fiber.Ctx for v3.
 import (
-    "github.com/gofiber/fiber/v3"
+    "github.com/gofiber/fiber/v3"
     "github.com/gofiber/contrib/fiberzerolog"
     "github.com/rs/zerolog"
+    "os"
 )
@@
-    app.Get("/", func (c *fiber.Ctx) error {
+    app.Get("/", func (c fiber.Ctx) error {
         return c.SendString("Hello, World!")
     })

Also applies to: 65-66


33-45: Update Config type signatures for Fiber v3 (value-based Ctx).

These entries still show pointer *fiber.Ctx. For v3 they should accept/return with fiber.Ctx.

-| Next          | `func(*Ctx) bool`              | Define a function to skip this middleware when returned true                                                                                                                                                | `nil`                                                                       |
+| Next          | `func(fiber.Ctx) bool`         | Define a function to skip this middleware when returned true                                                                                                                                                | `nil`                                                                       |
@@
-| GetLogger        | `func(*fiber.Ctx) zerolog.Logger`           | Get custom zerolog logger, if it's defined the returned logger will replace the `Logger` value.                                                                                                              | `nil`                                                      |
+| GetLogger        | `func(fiber.Ctx) zerolog.Logger`            | Get custom zerolog logger, if it's defined the returned logger will replace the `Logger` value.                                                                                                              | `nil`                                                      |
@@
-| GetResBody    | func(c *fiber.Ctx) []byte      | Define a function to get response body when return non-nil.<br />eg: When use compress middleware, resBody is unreadable. you can set GetResBody func to get readable resBody.                              | `nil` |
+| GetResBody    | `func(fiber.Ctx) []byte`       | Define a function to get response body when return non-nil.<br />eg: When using compression middleware, resBody is unreadable. You can set GetResBody to return a readable body.                            | `nil` |
fiberzerolog/config.go (1)

276-282: Guard against empty (non-nil) Messages/Levels to avoid panics.
If a user supplies an empty slice (not nil), indexing later will panic. Fill with defaults when len == 0.

Apply:

- if cfg.Messages == nil {
+ if cfg.Messages == nil || len(cfg.Messages) == 0 {
     cfg.Messages = ConfigDefault.Messages
 }
- if cfg.Levels == nil {
+ if cfg.Levels == nil || len(cfg.Levels) == 0 {
     cfg.Levels = ConfigDefault.Levels
 }
fiberzerolog/zerolog.go (1)

75-83: Bug: passing fiber.Ctx to zerolog’s Event.Ctx — use std context via c.Context().
zerolog.Event.Ctx expects context.Context. In Fiber v3, use c.Context() (renamed from UserContext()).

-       ctx := c
+       ctx := c.Context()
swagger/README.md (1)

100-106: Update Config.Next signature to Fiber v3 (value) Ctx.

Docs still show a pointer. For v3, handlers/config callbacks take fiber.Ctx by value.

-    Next func(c *fiber.Ctx) bool
+    Next func(c fiber.Ctx) bool
opafiber/README.md (2)

39-45: Align types and config callbacks to Fiber v3 value Ctx.

Docs use *fiber.Ctx; v3 uses fiber.Ctx by value. Update both the table default and the InputCreationFunc type.

-| InputCreationMethod   | `InputCreationFunc` | Use your own function to provide input for OPA               | `func defaultInput(ctx *fiber.Ctx) (map[string]interface{}, error)` |
+| InputCreationMethod   | `InputCreationFunc` | Use your own function to provide input for OPA               | `func defaultInput(ctx fiber.Ctx) (map[string]interface{}, error)` |
-type InputCreationFunc func(c *fiber.Ctx) (map[string]interface{}, error)
+type InputCreationFunc func(c fiber.Ctx) (map[string]interface{}, error)

85-98: Example won’t compile: missing bytes import and pointer Ctx usage.

Add bytes to imports and switch to value Ctx in the callback.

 import (
-	"github.com/gofiber/fiber/v3"
-	"github.com/gofiber/contrib/opafiber/v2"
+    "bytes"
+    "github.com/gofiber/fiber/v3"
+    "github.com/gofiber/contrib/opafiber/v2"
 )
@@
-        InputCreationMethod:   func (ctx *fiber.Ctx) (map[string]interface{}, error) {
+        InputCreationMethod:   func (ctx fiber.Ctx) (map[string]interface{}, error) {
             return map[string]interface{}{
-                "method": ctx.Method(),
-                "path": ctx.Path(),
+                "method": ctx.Method(),
+                "path":   ctx.Path(),
             }, nil
         },
otelfiber/README.md (2)

37-47: Update option signatures to Fiber v3 value Ctx.

Docs show pointers; v3 uses fiber.Ctx by value.

-| `WithNext`                    | `func(*fiber.Ctx) bool`         | Define a function to skip this middleware when returned true .| nil                                                                 |
+| `WithNext`                    | `func(fiber.Ctx) bool`          | Define a function to skip this middleware when returned true. | nil                                                                 |
@@
-| `WithSpanNameFormatter`       | `func(*fiber.Ctx) string`       | Takes a function that will be called on every request and the returned string will become the span Name.                                   | Default formatter returns the route pathRaw |
+| `WithSpanNameFormatter`       | `func(fiber.Ctx) string`        | Takes a function that will be called on every request and the returned string will become the span Name.                                   | Default formatter returns the route pathRaw |
@@
-| `WithCustomAttributes`        | `func(*fiber.Ctx) []attribute.KeyValue` | Define a function to add custom attributes to the span.                  | nil                                                                 |
+| `WithCustomAttributes`        | `func(fiber.Ctx) []attribute.KeyValue` | Define a function to add custom attributes to the span.                  | nil                                                                 |
@@
-| `WithCustomMetricAttributes`  | `func(*fiber.Ctx) []attribute.KeyValue` | Define a function to add custom attributes to the metrics.               | nil                                                                 |
+| `WithCustomMetricAttributes`  | `func(fiber.Ctx) []attribute.KeyValue` | Define a function to add custom attributes to the metrics.               | nil                                                                 |

96-100: Fix example: c.UserContext() → c.Context() (v3 rename) and JSON map key.

In v3, UserContext() was renamed to Context(). Also make the JSON key a string literal.

-    name := getUser(c.UserContext(), id)
-    return c.JSON(fiber.Map{"id": id, name: name})
+    name := getUser(c.Context(), id)
+    return c.JSON(fiber.Map{"id": id, "name": name})
fiberi18n/README.md (1)

26-31: *Signature table still shows fiber.Ctx; update to fiber.Ctx (v3)

The codebase migrated to by-value Ctx; docs should match.

-| Localize     | `Localize(ctx *fiber.Ctx, params interface{}) (string, error)` | Localize returns a localized message. param is one of these type: messageID, *i18n.LocalizeConfig                                      |
-| MustLocalize | `MustLocalize(ctx *fiber.Ctx, params interface{}) string`      | MustLocalize is similar to Localize, except it panics if an error happens. param is one of these type: messageID, *i18n.LocalizeConfig |
+| Localize     | `Localize(ctx fiber.Ctx, params interface{}) (string, error)`  | Localize returns a localized message. param is one of these type: messageID, *i18n.LocalizeConfig                                      |
+| MustLocalize | `MustLocalize(ctx fiber.Ctx, params interface{}) string`       | MustLocalize is similar to Localize, except it panics if an error happens. param is one of these type: messageID, *i18n.LocalizeConfig |
fibernewrelic/README.md (1)

37-39: Update Config function types to fiber.Ctx (v3)

Docs still show *fiber.Ctx.

-| ErrorStatusCodeHandler | `func(c *fiber.Ctx, err error) int`    | If you want to change newrelic status code, you can use it. | `DefaultErrorStatusCodeHandler` |
-| Next                   | `func(c *fiber.Ctx) bool`    | Next defines a function to skip this middleware when returned true.                                                           | `nil`                           |
+| ErrorStatusCodeHandler | `func(c fiber.Ctx, err error) int`     | If you want to change newrelic status code, you can use it. | `DefaultErrorStatusCodeHandler` |
+| Next                   | `func(c fiber.Ctx) bool`                | Next defines a function to skip this middleware when returned true.                       | `nil`                           |
fibersentry/README.md (1)

56-106: Use fiber.Ctx (by value) in handlers and BeforeSend cast

  • In fibersentry/README.md, change all handler signatures from func(c *fiber.Ctx) error to func(c fiber.Ctx) error to match the v3 Handler definition.
  • In the BeforeSend examples, replace the type assertion hint.Context.Value(...).(*fiber.Ctx) with .(fiber.Ctx) so you’re asserting the interface itself.
casbin/README.md (4)

32-40: Docs still reference pointer-based Ctx; update to fiber.Ctx for v3

The Config table should reflect by-value signatures in Fiber v3.

Apply:

-| Lookup        | `func(*fiber.Ctx) string` | Look up for current subject              | `""`                                                                |
-| Unauthorized  | `func(*fiber.Ctx) error`  | Response body for unauthorized responses | `Unauthorized`                                                      |
-| Forbidden     | `func(*fiber.Ctx) error`  | Response body for forbidden responses    | `Forbidden`                                                         |
+| Lookup        | `func(fiber.Ctx) string`  | Look up for current subject              | `""`                                                                |
+| Unauthorized  | `func(fiber.Ctx) error`   | Response body for unauthorized responses | `Unauthorized`                                                      |
+| Forbidden     | `func(fiber.Ctx) error`   | Response body for forbidden responses    | `Forbidden`                                                         |

63-66: Update example signatures to v3 (fiber.Ctx by value)

Handlers and Lookup still use *fiber.Ctx.

-      Lookup: func(c *fiber.Ctx) string {
+      Lookup: func(c fiber.Ctx) string {
...
-      func(c *fiber.Ctx) error {
+      func(c fiber.Ctx) error {
...
-    func(c *fiber.Ctx) error {
+    func(c fiber.Ctx) error {

Also applies to: 70-73, 77-80


104-107: RoutePermission example: switch to by-value Ctx

-  Lookup: func(c *fiber.Ctx) string {
+  Lookup: func(c fiber.Ctx) string {
...
-    func(c *fiber.Ctx) error {
+    func(c fiber.Ctx) error {

Also applies to: 112-115


139-142: RoleAuthorization example: switch to by-value Ctx

-  Lookup: func(c *fiber.Ctx) string {
+  Lookup: func(c fiber.Ctx) string {
...
-    func(c *fiber.Ctx) error {
+    func(c fiber.Ctx) error {

Also applies to: 146-149

fibersentry/sentry.go (1)

33-41: *Pass http.Request (not fiber.Ctx) into Sentry RecoverWithContext

RecoverWithContext expects a context carrying the request via sentry.RequestContextKey. You already have r from adaptor.ConvertRequest; use it to ensure proper request capture on panics.

-                eventID := hub.RecoverWithContext(
-                    context.WithValue(context.Background(), sentry.RequestContextKey, c),
-                    err,
-                )
+                eventID := hub.RecoverWithContext(
+                    context.WithValue(r.Context(), sentry.RequestContextKey, r),
+                    err,
+                )
jwt/utils.go (1)

19-31: Header extractor off-by-one can reject minimal valid tokens

len(auth) > l+1 wrongly requires two extra chars beyond the scheme+space. Use > l so at least one char after the space is accepted.

-        if len(auth) > l+1 && strings.EqualFold(auth[:l], authScheme) {
+        if len(auth) > l && strings.EqualFold(auth[:l], authScheme) {
             return strings.TrimSpace(auth[l:]), nil
         }

Optionally add a test for a single-char token to prevent regressions.

socketio/socketio_test.go (1)

132-166: WaitGroup leak on error paths → test can hang.

Several early returns skip wg.Done(). Defer it at goroutine start and defer dial.Close() after a successful dial.

- for i := 0; i < numParallelTestConn; i++ {
+ for i := 0; i < numParallelTestConn; i++ {
     wg.Add(1)
     go func() {
+      defer wg.Done()
       dialer := &websocket.Dialer{
         NetDial: func(network, addr string) (net.Conn, error) {
           return ln.Dial()
         },
         HandshakeTimeout: 45 * time.Second,
       }
       dial, _, err := dialer.Dial(wsURL, nil)
       if err != nil {
         t.Error(err)
         return
       }
+      defer func() {
+        _ = dial.Close()
+      }()
 
       if err := dial.WriteMessage(websocket.TextMessage, []byte("test")); err != nil {
         t.Error(err)
         return
       }
 
       tp, m, err := dial.ReadMessage()
       if err != nil {
         t.Error(err)
         return
       }
       require.Equal(t, TextMessage, tp)
       require.Equal(t, "response", string(m))
-      wg.Done()
-
-      if err := dial.Close(); err != nil {
-        t.Error(err)
-        return
-      }
     }()
   }
loadshed/loadshed.go (1)

16-22: Fix OnShed doc to match behavior
At loadshed/loadshed.go:19–20, the comment is incorrect—returning nil without calling c.Next() actually halts the chain. Update to:

- // Returning `nil` without writing to the response context allows the
- // request to proceed to the next handler
+ // To proceed, call and return `c.Next()`.
+ // Returning `nil` (without `c.Next()`) stops the handler chain.
opafiber/fiber.go (1)

30-40: fmt.Sprint used with formatting verbs — error detail lost.

fmt.Sprint doesn’t process %w; the panic message drops the underlying error.

- readedBytes, err := io.ReadAll(cfg.RegoPolicy)
+ policyBytes, err := io.ReadAll(cfg.RegoPolicy)
  if err != nil {
-   panic(fmt.Sprint("could not read rego policy %w", err))
+   panic(fmt.Errorf("could not read rego policy: %w", err))
  }
  query, err := rego.New(
    rego.Query(cfg.RegoQuery),
-   rego.Module("policy.rego", utils.UnsafeString(readedBytes)),
+   rego.Module("policy.rego", utils.UnsafeString(policyBytes)),
  ).PrepareForEval(context.Background())
  if err != nil {
-   panic(fmt.Sprint("rego policy error: %w", err))
+   panic(fmt.Errorf("rego policy error: %w", err))
  }

Also renames readedBytes → policyBytes for clarity.

loadshed/README.md (4)

36-64: Examples: update handlers to fiber.Ctx (value) for v3.
Current examples still use *fiber.Ctx.

-  app.Get("/", func(c *fiber.Ctx) error {
+  app.Get("/", func(c fiber.Ctx) error {
     return c.SendString("Welcome!")
   })

66-109: *Custom rejection example: update imports already v3, but OnShed/handlers still use fiber.Ctx.
Align to v3 and example style.

-    OnShed: func(ctx *fiber.Ctx) error {
+    OnShed: func(ctx fiber.Ctx) error {
@@
-  app.Get("/", func(c *fiber.Ctx) error {
+  app.Get("/", func(c fiber.Ctx) error {
     return c.SendString("Welcome!")
   })

115-120: Config table types out of date for v3 (pointer → value).

-| Next     | `func(*fiber.Ctx) bool`    | Function to skip this middleware when returned true.    | `nil`                   |
+| Next     | `func(fiber.Ctx) bool`     | Function to skip this middleware when returned true.    | `nil`                   |
@@
-| OnShed   | `func(c *fiber.Ctx) error` | Function to be executed if a request should be declined | `nil`                   |
+| OnShed   | `func(c fiber.Ctx) error`  | Function to be executed if a request should be declined | `nil`                   |

147-149: Fix rejection probability formula (mixes percent and fraction).
Use normalized CPU value.

-    rejectionProbability := (cpuUsage - LowerThreshold*100) / (UpperThreshold - LowerThreshold)
+    rejectionProbability := (cpuUsage/100 - LowerThreshold) / (UpperThreshold - LowerThreshold)
circuitbreaker/circuitbreaker.go (1)

238-244: Drain or reinitialize the half-open semaphore on transition.

This drains at most one token. Leftover tokens from a prior half-open window reduce capacity unexpectedly. Reinitialize the channel to a fresh buffered chan.

-		// Empty the semaphore channel
-		select {
-		case <-cb.halfOpenSemaphore:
-		default:
-		}
+		// Reset the semaphore to enforce fresh capacity for the new half-open window
+		cb.halfOpenSemaphore = make(chan struct{}, cb.config.HalfOpenMaxConcurrent)
circuitbreaker/README.md (3)

56-60: Config table types don’t match v3 API

Update function types to use value-based fiber.Ctx and include Ctx parameter for IsFailure.

-| IsFailure | `func(error) bool` | Custom function to determine if an error is a failure | `Status >= 500` |
-| OnOpen | `func(*fiber.Ctx)` | Callback function when the circuit is opened | `503 response` |
-| OnClose | `func(*fiber.Ctx)` | Callback function when the circuit is closed | `Continue request` |
-| OnHalfOpen | `func(*fiber.Ctx)` | Callback function when the circuit is half-open | `429 response` |
+| IsFailure | `func(c fiber.Ctx, err error) bool` | Custom function to determine if an error is a failure | `Status >= 500 or err != nil` |
+| OnOpen | `func(fiber.Ctx) error` | Callback when the circuit opens | `503 response` |
+| OnClose | `func(fiber.Ctx) error` | Callback when the circuit closes | `Continue request` |
+| OnHalfOpen | `func(fiber.Ctx) error` | Callback when the circuit is half-open | `429 response` |

75-83: Update examples to Fiber v3 (value Ctx, grouping, config fields, external calls)

Multiple examples still use *fiber.Ctx, an undefined route.Group, an outdated HalfOpenSemaphore field, and fiber.Get (non-existent client).

Apply:

@@
-import (
-	"github.com/gofiber/fiber/v3"
-	"github.com/gofiber/contrib/circuitbreaker"
-)
+import (
+	"time"
+	"github.com/gofiber/fiber/v3"
+	"github.com/gofiber/contrib/circuitbreaker"
+)
@@
-app.Get("/", func(c *fiber.Ctx) error {
+app.Get("/", func(c fiber.Ctx) error {
 	return c.SendString("Hello, world!")
 })
@@
-app.Get("/metrics/circuit", func(c *fiber.Ctx) error {
- 		return c.JSON(cb.GetStateStats())
+app.Get("/metrics/circuit", func(c fiber.Ctx) error {
+	return c.JSON(cb.GetStateStats())
 })
@@
-app.Get("/protected", circuitbreaker.Middleware(cb), func(c *fiber.Ctx) error {
+app.Get("/protected", circuitbreaker.Middleware(cb), func(c fiber.Ctx) error {
 	return c.SendString("Protected service running")
 })
@@
-app := route.Group("/api")
-app.Use(circuitbreaker.Middleware(cb))
+api := app.Group("/api")
+api.Use(circuitbreaker.Middleware(cb))
@@
-app.Get("/users", getUsersHandler)
-app.Post("/users", createUserHandler)
+api.Get("/users", getUsersHandler)
+api.Post("/users", createUserHandler)
@@
-OnOpen: func(c *fiber.Ctx) error {
+OnOpen: func(c fiber.Ctx) error {
@@
-OnHalfOpen: func(c *fiber.Ctx) error {
+OnHalfOpen: func(c fiber.Ctx) error {
@@
-OnClose: func(c *fiber.Ctx) error {
+OnClose: func(c fiber.Ctx) error {
@@
-app.Get("/external-api", circuitbreaker.Middleware(cb), func(c *fiber.Ctx) error {
-	// Simulating an external API call
-	resp, err := fiber.Get("https://example.com/api")
-	if err != nil {
-		return fiber.NewError(fiber.StatusInternalServerError, "External API failed")
-	}
-	return c.SendString(resp.Body())
+app.Get("/external-api", circuitbreaker.Middleware(cb), func(c fiber.Ctx) error {
+	// Example using net/http client
+	resp, err := http.Get("https://example.com/api")
+	if err != nil {
+		return fiber.NewError(fiber.StatusBadGateway, "External API failed")
+	}
+	defer resp.Body.Close()
+	body, _ := io.ReadAll(resp.Body)
+	return c.Status(resp.StatusCode).Send(body)
 })
@@
-cb := circuitbreaker.New(circuitbreaker.Config{
-	FailureThreshold:  3,
-	Timeout:           5 * time.Second,
-	SuccessThreshold:  2,
-	HalfOpenSemaphore: make(chan struct{}, 2), // Allow only 2 concurrent requests
-})
+cb := circuitbreaker.New(circuitbreaker.Config{
+	FailureThreshold:      3,
+	Timeout:               5 * time.Second,
+	SuccessThreshold:      2,
+	HalfOpenMaxConcurrent: 2, // Allow only 2 concurrent requests
+})
@@
-app.Get("/db-service", circuitbreaker.Middleware(dbCB), func(c *fiber.Ctx) error {
+app.Get("/db-service", circuitbreaker.Middleware(dbCB), func(c fiber.Ctx) error {
@@
-app.Get("/api-service", circuitbreaker.Middleware(apiCB), func(c *fiber.Ctx) error {
+app.Get("/api-service", circuitbreaker.Middleware(apiCB), func(c fiber.Ctx) error {

Additionally, replace the shutdown snippet with a simpler, correct pattern:

defer cb.Stop() // ensure breaker stops on app exit

Also applies to: 93-113, 120-133, 140-161, 170-179, 188-199, 226-237


45-46: Update New signature in docs
Replace in circuitbreaker/README.md (lines 45–46):

- circuitbreaker.New(config ...circuitbreaker.Config) *circuitbreaker.Middleware 
+ circuitbreaker.New(config circuitbreaker.Config) *circuitbreaker.CircuitBreaker
fibernewrelic/fiber.go (1)

73-81: Attach New Relic transaction to Fiber context
Insert immediately after starting the transaction:

// Attach New Relic transaction to Fiber’s context for downstream retrieval
// Fiber v3: use c.Context() (formerly UserContext) and SetContext()
c.SetContext(newrelic.NewContext(c.Context(), txn))
otelfiber/otelfiber_test/fiber_test.go (3)

370-401: Fix histogram helper: wrong slice increment and potential out-of-bounds.

When value exceeds last bound you should increment the extra bucket in bucketCounts, not mutate bounds.

@@
-    for i, v := range bounds {
+    for i, v := range bounds {
         if value <= v {
             bucketCounts[i]++
             break
         }
 
-        if i == len(bounds)-1 {
-            bounds[i+1]++
-            break
-        }
+        if i == len(bounds)-1 {
+            // value > last bound => increment the overflow bucket
+            bucketCounts[len(bounds)]++
+            break
+        }
     }

553-561: Avoid setting global OTel provider inside parallel subtests.

otel.SetTracerProvider is global; calling it in t.Parallel() subtests can race. You already inject the provider via middleware; remove the global set.

-            sr := tracetest.NewSpanRecorder()
-            provider := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(sr))
-            otel.SetTracerProvider(provider)
+            sr := tracetest.NewSpanRecorder()
+            provider := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(sr))

496-515: Use the span’s ctx for propagation instead of the raw c
Replace in otelfiber/fiber.go around line 175:

-    cfg.Propagators.Inject(c, tracingHeaders)
+    cfg.Propagators.Inject(ctx, tracingHeaders)

so the ctx returned by tracer.Start is used for injection, ensuring the correct span context is propagated.

fiberzap/README.md (1)

33-43: Config table types are outdated for v3 (value Ctx).

Update types to match the v3 API: Next, GetResBody, SkipBody, SkipResBody, and FieldsFunc should accept fiber.Ctx (by value), and FieldsFunc is a function, not []zap.Field.

-| Next       | `func(*Ctx) bool`          | Define a function to skip this middleware when returned true                                         | `nil` |
+| Next       | `func(fiber.Ctx) bool`     | Define a function to skip this middleware when returned true                                         | `nil` |
...
-| FieldsFunc | `[]zap.Field`              | Define a function to add custom fields.                                                              | `nil` |
+| FieldsFunc | `func(fiber.Ctx) []zap.Field` | Define a function to add custom fields.                                                            | `nil` |
...
-| GetResBody | func(c \*fiber.Ctx) []byte | Define a function to get response body when return non-nil.                                         | `nil` |
+| GetResBody | `func(fiber.Ctx) []byte`   | Define a function to get response body when return non-nil.                                         | `nil` |
fiberzap/zap.go (1)

112-114: Bug: logging err (always nil) instead of the actual chainErr.

This drops error details from logs. Log chainErr (when non-nil) or remove the unconditional error field to avoid duplication with the "error" case below.

-        fields := make([]zap.Field, 0, len(cfg.Fields)+1)
-        fields = append(fields, zap.Error(err))
+        fields := make([]zap.Field, 0, len(cfg.Fields)+1)
+        if chainErr != nil {
+            fields = append(fields, zap.Error(chainErr))
+        }
fiberzap/logger.go (3)

98-105: Duplicate removal logic is a no-op; actually deduplicate ExtraKeys.

Looping over cfg.ExtraKeys and checking membership in the same slice never removes dups. Build a set instead.

- // Remove duplicated extraKeys
- for _, k := range cfg.ExtraKeys {
-   if !contains(k, cfg.ExtraKeys) {
-     cfg.ExtraKeys = append(cfg.ExtraKeys, k)
-   }
- }
+ // Deduplicate ExtraKeys
+ if len(cfg.ExtraKeys) > 1 {
+   seen := make(map[string]struct{}, len(cfg.ExtraKeys))
+   uniq := make([]string, 0, len(cfg.ExtraKeys))
+   for _, k := range cfg.ExtraKeys {
+     if _, ok := seen[k]; ok {
+       continue
+     }
+     seen[k] = struct{}{}
+     uniq = append(uniq, k)
+   }
+   cfg.ExtraKeys = uniq
+ }

129-145: Guard against empty CoreConfigs to avoid panics in SetOutput.

l.CoreConfigs[0] panics if a user supplied an empty (non-nil) slice. Initialize a default core when empty.

 func (l *LoggerConfig) SetOutput(w io.Writer) {
   if l.SetLogger != nil {
     fiberlog.Warn("SetOutput is ignored when SetLogger is set")
     return
   }
-  l.CoreConfigs[0].WriteSyncer = zapcore.AddSync(w)
+  if len(l.CoreConfigs) == 0 {
+    l.CoreConfigs = []CoreConfig{
+      {
+        Encoder:      zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()),
+        WriteSyncer:  zapcore.AddSync(w),
+        LevelEncoder: zap.NewAtomicLevelAt(zap.InfoLevel),
+      },
+    }
+  } else {
+    l.CoreConfigs[0].WriteSyncer = zapcore.AddSync(w)
+  }

147-178: Same empty-slice guard needed in SetLevel.

Avoid l.CoreConfigs[0] when CoreConfigs is empty.

 func (l *LoggerConfig) SetLevel(lv fiberlog.Level) {
   if l.SetLogger != nil {
     fiberlog.Warn("SetLevel is ignored when SetLogger is set")
     return
   }
@@
- l.CoreConfigs[0].LevelEncoder = level
+ if len(l.CoreConfigs) == 0 {
+   l.CoreConfigs = []CoreConfig{
+     {
+       Encoder:      zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()),
+       WriteSyncer:  zapcore.AddSync(os.Stdout),
+       LevelEncoder: level,
+     },
+   }
+ } else {
+   l.CoreConfigs[0].LevelEncoder = level
+ }
fiberi18n/embed_test.go (1)

51-53: Update App.Test call for Fiber v3.

Fiber v3’s App.Test takes a fiber.TestConfig. Pass an empty config for defaults.

- resp, err := embedApp.Test(req)
+ resp, err := embedApp.Test(req, fiber.TestConfig{})
websocket/websocket_test.go (1)

74-83: Potential panic: unconditional defer conn.Close() when Dial fails.

In the “disallowed origin” case, conn is nil on handshake error; deferring conn.Close() will panic.

Use a guarded cleanup:

conn, resp, err := websocket.DefaultDialer.Dial(url, hdr)
if conn != nil {
	t.Cleanup(func() { _ = conn.Close() })
}
assert.Error(t, err)

Recommend applying the same pattern to all Dial sites.

fiberi18n/i18n.go (2)

75-84: Fix examples: use ctx.Params("name") instead of context.Param.
Public docs should reflect Fiber’s API; singular Param is incorrect.

Apply:

-					"name": context.Param("name"),
+					"name": ctx.Params("name"),

125-131: Validate params type; avoid passing nil LocalizeConfig.
If params is neither string nor *i18n.LocalizeConfig, localizeConfig stays nil; be explicit and return an error.

 switch paramValue := params.(type) {
 case string:
   localizeConfig = &i18n.LocalizeConfig{MessageID: paramValue}
 case *i18n.LocalizeConfig:
   localizeConfig = paramValue
+default:
+  return "", fmt.Errorf("i18n.Localize error: unsupported params type %T", params)
 }
 
 message, err := localizer.(*i18n.Localizer).Localize(localizeConfig)

Also applies to: 133-139

fiberi18n/i18n_test.go (1)

219-233: Do not call testing.T methods from goroutines.

Using assert with t inside goroutines is unsafe and can race. Collect errors via channel and assert after wg.Wait, or spawn subtests with t.Run and t.Parallel.

Example (channel aggregation):

 t.Run("test nil ctx", func(t *testing.T) {
   var wg sync.WaitGroup
   want := 100
+  errs := make(chan error, want)
   wg.Add(want)
   for i := 0; i < want; i++ {
     go func() {
       defer wg.Done()
       got, err := makeRequest(language.English, "", app)
-      assert.Equal(t, nil, err)
+      if err != nil { errs <- err; return }
+      defer got.Body.Close()
       body, _ := io.ReadAll(got.Body)
-      assert.Equal(t, "en", string(body))
+      if string(body) != "en" { errs <- fmt.Errorf("want en, got %q", body) }
     }()
   }
   wg.Wait()
+  close(errs)
+  for e := range errs {
+    assert.NoError(t, e)
+  }
 })
jwt/README.md (2)

254-258: Remove or rewrite JWK Set section; field was removed in v3.

Docs still reference JWKSetURLs, which v3 removes per the migration notes/PR context. This will mislead users. Replace with v3-supported approach or delete. (docs.gofiber.io)

-## JWK Set Test
-
-The tests are identical to basic `JWT` tests above, with exception that `JWKSetURLs` to valid public keys collection in JSON Web Key (JWK) Set format should be supplied. See [RFC 7517](https://www.rfc-editor.org/rfc/rfc7517).
+<!-- JWK Set config was removed in v3. If/when JWK support returns, document the new configuration/API here. -->

260-306: Delete “Custom KeyFunc example” (removed in v3).

KeyFunc is no longer a public config field in v3. Keeping this section contradicts the v3 API and examples. (docs.gofiber.io)

-## Custom KeyFunc example
-... (entire section)
+<!-- KeyFunc was removed in v3. If a new extension point exists, add an up-to-date example here. -->

Comment on lines +73 to +78
mapfile -t MODULE_DIRS < <(
find . \( -path "./.git" -o -path "./vendor" -o -path "./node_modules" \) -prune -o \
-type f -name 'go.mod' -print0 |
xargs -0 -n1 dirname |
sort -u
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Broaden prunes to nested .git/vendor/node_modules.

Current patterns only skip top-level directories. Use globs to avoid scanning vendored or nested modules.

-  find . \( -path "./.git" -o -path "./vendor" -o -path "./node_modules" \) -prune -o \
+  find . \( -path "*/.git" -o -path "*/vendor" -o -path "*/node_modules" \) -prune -o \
     -type f -name 'go.mod' -print0 |
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
mapfile -t MODULE_DIRS < <(
find . \( -path "./.git" -o -path "./vendor" -o -path "./node_modules" \) -prune -o \
-type f -name 'go.mod' -print0 |
xargs -0 -n1 dirname |
sort -u
)
mapfile -t MODULE_DIRS < <(
find . \( -path "*/.git" -o -path "*/vendor" -o -path "*/node_modules" \) -prune -o \
-type f -name 'go.mod' -print0 |
xargs -0 -n1 dirname |
sort -u
)
🤖 Prompt for AI Agents
In .github/scripts/parallel-go-test.sh around lines 73 to 78, the find command
only prunes top-level .git, vendor and node_modules directories; update the
prune patterns to match nested directories (e.g. use globs/leading-wildcard
paths like */.git, */vendor, */node_modules) so find will skip any nested
vendored or git folders; ensure the new -path patterns are quoted and combined
with -o before -prune, and keep the rest of the pipeline (-type f -name 'go.mod'
-print0 | xargs -0 -n1 dirname | sort -u) unchanged.

Comment on lines +145 to +157
if ! grep -E -q '(--- FAIL:|^FAIL\b|panic:|exit status|FAIL\t|FAIL:)' "$src_log"; then
# nothing to do (only PASS/ok output)
rm -f "$src_log" >/dev/null 2>&1 || true
return
fi

local annotated
annotated="$(mktemp "$TMPDIR/annotated.XXXXXX")" || {
until mkdir "$lockdir" 2>/dev/null; do sleep 0.01; done
printf '==== %s ====\n' "$module_dir" >> "$LOGFILE"
# filter out PASS/OK noise when falling back
grep -v -E '^(=== RUN|--- PASS:|^PASS$|^ok\s)' "$src_log" >> "$LOGFILE" || true
rm -f "$src_log" || true
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix regex usage: \s and \b aren’t supported here; may miss failures and skip lines incorrectly.

  • grep -E doesn’t support \b or \s. Use POSIX classes.
  • Bash [[ … =~ … ]] also doesn’t support \s.

Apply:

-  if ! grep -E -q '(--- FAIL:|^FAIL\b|panic:|exit status|FAIL\t|FAIL:)' "$src_log"; then
+  if ! grep -E -q '(--- FAIL:|^FAIL($|[[:space:]])|panic:|exit status|FAIL[[:space:]]|FAIL:)' "$src_log"; then
@@
-    grep -v -E '^(=== RUN|--- PASS:|^PASS$|^ok\s)' "$src_log" >> "$LOGFILE" || true
+    grep -v -E '^(=== RUN|--- PASS:|PASS$|ok[[:space:]])' "$src_log" >> "$LOGFILE" || true
@@
-    if [[ $line =~ ^(===\ RUN|---\ PASS:|^PASS$|^ok\s) ]]; then
+    if [[ $line =~ ^(===\ RUN|---\ PASS:|PASS$|ok[[:space:]]) ]]; then
       continue
     fi

Also applies to: 163-167

🤖 Prompt for AI Agents
In .github/scripts/parallel-go-test.sh around lines 145-157 (and similarly lines
163-167), the extended grep regex uses \b and \s which are unsupported by grep
-E; change those to POSIX character classes and explicit anchors. Replace
patterns like ^FAIL\b and FAIL\t with FAIL([[:space:]]|$) or
^FAIL([[:space:]]|$) (or simply FAIL[[:space:]]), and replace ^ok\s with
^ok[[:space:]]; update both the grep -E -q '(--- FAIL:|^FAIL\b|panic:|exit
status|FAIL\t|FAIL:)' and the grep -v -E '^(=== RUN|--- PASS:|^PASS$|^ok\s)'
calls to use the POSIX-style alternatives so grep -E correctly matches
whitespace and word boundaries.

Comment on lines +170 to +175
if [[ $line =~ ^([^:]+\.go):([0-9]+):?([0-9]*)[:[:space:]]*(.*)$ ]]; then
local fp="${BASH_REMATCH[1]}"
local ln="${BASH_REMATCH[2]}"
local col="${BASH_REMATCH[3]}"
local rest="${BASH_REMATCH[4]}"
local candidate=""
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Correct file:line[:col] matcher; also use captured column (fixes ShellCheck SC2034).

  • Current [:[:space:]]* is malformed; column is captured but unused.
  • Emit :col when available.

Apply:

-    if [[ $line =~ ^([^:]+\.go):([0-9]+):?([0-9]*)[:[:space:]]*(.*)$ ]]; then
+    if [[ $line =~ ^([^:]+\.go):([0-9]+)(:([0-9]+))?[[:space:]]*(.*)$ ]]; then
       local fp="${BASH_REMATCH[1]}"
       local ln="${BASH_REMATCH[2]}"
-      local col="${BASH_REMATCH[3]}"
-      local rest="${BASH_REMATCH[4]}"
+      local col="${BASH_REMATCH[4]}"
+      local rest="${BASH_REMATCH[5]}"
@@
-      if [ -n "$candidate" ]; then
+      if [ -n "$candidate" ]; then
         local start=$(( ln > 1 ? ln - 1 : 1 ))
         local end=$(( ln + 1 ))
-        printf '%s\n' "---- source: $candidate:$ln ----" >> "$annotated"
+        if [ -n "$col" ]; then
+          printf '%s\n' "---- source: $candidate:$ln:$col ----" >> "$annotated"
+        else
+          printf '%s\n' "---- source: $candidate:$ln ----" >> "$annotated"
+        fi
         awk -v s="$start" -v e="$end" 'NR>=s && NR<=e { printf("%6d  %s\n", NR, $0) }' "$candidate" >> "$annotated"
         printf '%s\n\n' "Error: $line" >> "$annotated"

Also applies to: 185-191

🧰 Tools
🪛 Shellcheck (0.10.0)

[warning] 173-173: col appears unused. Verify use (or export if used externally).

(SC2034)

🤖 Prompt for AI Agents
.github/scripts/parallel-go-test.sh around lines 170-175 (and similarly update
185-191): the regex character class is malformed and the captured column is
unused (triggering ShellCheck SC2034); change the pattern portion
`[:[:space:]]*` to the correct POSIX class `[[:space:]]*` and ensure you emit
the column when present by appending `:${col}` (only when col is non-empty) to
the file:line string so the captured `col` variable is actually used.

Comment on lines +59 to 61
OnClose: func(c fiber.Ctx) error {
return c.Next()
},
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Default OnClose should be a no-op; calling Next() here risks double-invocation.

Middleware already calls c.Next() before invoking OnClose. The default OnClose: c.Next() can cause “next called multiple times” or re-enter handlers.

-	OnClose: func(c fiber.Ctx) error {
-		return c.Next()
-	},
+	OnClose: func(c fiber.Ctx) error {
+		return nil
+	},
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
OnClose: func(c fiber.Ctx) error {
return c.Next()
},
OnClose: func(c fiber.Ctx) error {
return nil
},
🤖 Prompt for AI Agents
In circuitbreaker/circuitbreaker.go around lines 59 to 61, the default OnClose
handler calls c.Next(), which can double-invoke the next handler because
Middleware already calls c.Next() before invoking OnClose; change the default to
a true no-op (do not call c.Next()) by replacing the function body to simply
return nil (or set OnClose to nil) so OnClose does not re-enter the handler
chain.

Comment thread fgprof/fgprof_test.go
Comment on lines 56 to 60
// Default fgprof interval is 30 seconds
resp, err := app.Test(httptest.NewRequest("GET", "/debug/fgprof?seconds=1", nil), 1500)
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, 200, resp.StatusCode)
resp, err := app.Test(httptest.NewRequest("GET", "/debug/fgprof?seconds=1", nil), fiber.TestConfig{Timeout: 1500})
assert.Equal(t, nil, err)
assert.Equal(t, 200, resp.StatusCode)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Timeout unit: confirm TestConfig.Timeout type and use duration if applicable

If fiber.TestConfig.Timeout is time.Duration in v3, pass 1500*time.Millisecond; if it’s int ms, current code is fine.

Suggested change if time.Duration:

- resp, err := app.Test(httptest.NewRequest("GET", "/debug/fgprof?seconds=1", nil), fiber.TestConfig{Timeout: 1500})
+ resp, err := app.Test(httptest.NewRequest("GET", "/debug/fgprof?seconds=1", nil), fiber.TestConfig{Timeout: 1500 * time.Millisecond})

🏁 Script executed:

#!/bin/bash
# Check TestConfig.Timeout type in your workspace
rg -nP 'type\s+TestConfig\s+struct\s*{[^}]*\bTimeout\b' $(go env GOPATH 2>/dev/null)/pkg/mod -g '!**/vendor/**' -S -C2

Length of output: 192


🏁 Script executed:

#!/bin/bash
# Search for TestConfig struct definition and its Timeout field type in this repository
rg -nP "type\s+TestConfig\s+struct" -C5 --type go .
rg -nP "TestConfig.*Timeout" -C3 --type go .

Length of output: 13760


Use time.Duration for TestConfig.Timeout
TestConfig.Timeout is a time.Duration (1 = 1 ns) – passing 1500 sets 1500 ns, not 1.5 s; change to 1500 * time.Millisecond and import time. (docs.gofiber.io)

- resp, err := app.Test(httptest.NewRequest("GET", "/debug/fgprof?seconds=1", nil), fiber.TestConfig{Timeout: 1500})
+ resp, err := app.Test(httptest.NewRequest("GET", "/debug/fgprof?seconds=1", nil), fiber.TestConfig{Timeout: 1500 * time.Millisecond})

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In fgprof/fgprof_test.go around lines 56 to 60 the TestConfig.Timeout is being
passed as an integer literal 1500 which is interpreted as nanoseconds; change
the timeout to a time.Duration value (e.g. 1500 * time.Millisecond or
time.Second) and add an import for time at the top of the file so the test uses
the intended 1.5s timeout.

Comment thread paseto/config_test.go
Comment on lines +27 to 28
assert.Equal(t, symmetricKey+symmetricKey, config.SymmetricKey)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify expected behavior for invalid symmetric key

Asserting key duplication is fine if configDefault enforces required length by repetition; confirm this logic matches paseto/config.go.


🏁 Script executed:

#!/bin/bash
# Inspect how SymmetricKey is normalized
rg -nP 'SymmetricKey|configDefault\(' paseto -C3 --type go

Length of output: 8967


🏁 Script executed:

#!/bin/bash
# Inspect the default ConfigDefault declaration and its SymmetricKey value
rg -nP 'var\s+ConfigDefault' paseto/config.go -C10

Length of output: 715


🏁 Script executed:

#!/bin/bash
rg -nP 'func configDefault' -C20 paseto/config.go

Length of output: 1179


Test_Config_Invalid_SymmetricKey mismatch – configDefault panics on invalid SymmetricKey length rather than concatenating the key to meet chacha20poly1305.KeySize. Either remove the duplication assertion in paseto/config_test.go (lines 27–28) and only assert the panic, or add normalization logic to configDefault to repeat the key as the test expects.

🤖 Prompt for AI Agents
paseto/config_test.go lines 27-28: the test expects configDefault to normalize a
too-short SymmetricKey by repeating it to chacha20poly1305.KeySize, but
configDefault currently panics on invalid length; modify configDefault to
normalize keys instead of panicking — when SymmetricKey length is less than
chacha20poly1305.KeySize, repeat the key bytes (concatenate copies) and truncate
to exactly KeySize; when longer, truncate to KeySize; then remove the panic so
the test asserting symmetricKey+symmetricKey (or equivalent repeated key)
passes.

Comment thread paseto/README.md
Comment on lines 38 to 43
| Property | Type | Description | Default |
|:---------------|:--------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------|
| Next | `func(*Ctx) bool` | Defines a function to skip middleware | `nil` |
| SuccessHandler | `func(*fiber.Ctx) error` | SuccessHandler defines a function which is executed for a valid token. | `c.Next()` |
| ErrorHandler | `func(*fiber.Ctx, error) error` | ErrorHandler defines a function which is executed for an invalid token. | `401 Invalid or expired PASETO` |
| SuccessHandler | `func(fiber.Ctx) error` | SuccessHandler defines a function which is executed for a valid token. | `c.Next()` |
| ErrorHandler | `func(fiber.Ctx, error) error` | ErrorHandler defines a function which is executed for an invalid token. | `401 Invalid or expired PASETO` |
| Validate | `PayloadValidator` | Defines a function to validate if payload is valid. Optional. In case payload used is created using `CreateToken` function. If token is created using another function, this function must be provided. | `nil` |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix type in Config table: Next should use fiber.Ctx (by value).

The table still shows func(*Ctx) bool. It should be func(fiber.Ctx) bool to match v3 and the code.

-| Next           | `func(*Ctx) bool`               | Defines a function to skip middleware                                                   | `nil`                           |
+| Next           | `func(fiber.Ctx) bool`          | Defines a function to skip middleware                                                   | `nil`                           |
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
| Property | Type | Description | Default |
|:---------------|:--------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------|
| Next | `func(*Ctx) bool` | Defines a function to skip middleware | `nil` |
| SuccessHandler | `func(*fiber.Ctx) error` | SuccessHandler defines a function which is executed for a valid token. | `c.Next()` |
| ErrorHandler | `func(*fiber.Ctx, error) error` | ErrorHandler defines a function which is executed for an invalid token. | `401 Invalid or expired PASETO` |
| SuccessHandler | `func(fiber.Ctx) error` | SuccessHandler defines a function which is executed for a valid token. | `c.Next()` |
| ErrorHandler | `func(fiber.Ctx, error) error` | ErrorHandler defines a function which is executed for an invalid token. | `401 Invalid or expired PASETO` |
| Validate | `PayloadValidator` | Defines a function to validate if payload is valid. Optional. In case payload used is created using `CreateToken` function. If token is created using another function, this function must be provided. | `nil` |
| Property | Type | Description | Default |
|:---------------|:--------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------|
| Next | `func(fiber.Ctx) bool` | Defines a function to skip middleware | `nil` |
| SuccessHandler | `func(fiber.Ctx) error` | SuccessHandler defines a function which is executed for a valid token. | `c.Next()` |
| ErrorHandler | `func(fiber.Ctx, error) error` | ErrorHandler defines a function which is executed for an invalid token. | `401 Invalid or expired PASETO` |
| Validate | `PayloadValidator` | Defines a function to validate if payload is valid. Optional. In case payload used is created using `CreateToken` function. If token is created using another function, this function must be provided. | `nil` |
🧰 Tools
🪛 LanguageTool

[grammar] ~42-~42: There might be a mistake here.
Context: ... | 401 Invalid or expired PASETO | | Validate | PayloadValidator ...

(QB_NEW_EN)


[grammar] ~43-~43: There might be a mistake here.
Context: ...idate if payload is valid. Optional. In case payload used is created using `CreateTo...

(QB_NEW_EN)


[grammar] ~43-~43: There might be a mistake here.
Context: ...s created using CreateToken function. If token is created using another function...

(QB_NEW_EN)

🤖 Prompt for AI Agents
In paseto/README.md around lines 38 to 43, the Config table incorrectly lists
Next as `func(*Ctx) bool`; update the table entry to `func(fiber.Ctx) bool` so
it matches v3 and the actual code signature. Edit only the table cell for Next's
Type to use the non-pointer fiber.Ctx type and ensure any surrounding formatting
remains intact.

Comment thread paseto/README.md
Comment on lines +128 to 131
func restricted(c fiber.Ctx) error {
payload := pasetoware.FromContext(c).(string)
return c.SendString("Welcome " + payload)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use safe FromContext assertions in README examples to avoid panics.

Direct .() assertions will panic if middleware is bypassed/misconfigured. Show a defensive pattern in examples.

@@
-func restricted(c fiber.Ctx) error {
-    payload := pasetoware.FromContext(c).(string)
-    return c.SendString("Welcome " + payload)
-}
+func restricted(c fiber.Ctx) error {
+    v := pasetoware.FromContext(c)
+    payload, ok := v.(string)
+    if !ok {
+        return c.SendStatus(fiber.StatusUnauthorized)
+    }
+    return c.SendString("Welcome " + payload)
+}
@@
-func restricted(c fiber.Ctx) error {
-    payload := pasetoware.FromContext(c).(customPayloadStruct)
-    return c.SendString("Welcome " + payload.Name)
-}
+func restricted(c fiber.Ctx) error {
+    v := pasetoware.FromContext(c)
+    payload, ok := v.(customPayloadStruct)
+    if !ok {
+        return c.SendStatus(fiber.StatusUnauthorized)
+    }
+    return c.SendString("Welcome " + payload.Name)
+}
@@
-func restricted(c fiber.Ctx) error {
-    payload := pasetoware.FromContext(c).(string)
-    return c.SendString("Welcome " + payload)
-}
+func restricted(c fiber.Ctx) error {
+    v := pasetoware.FromContext(c)
+    payload, ok := v.(string)
+    if !ok {
+        return c.SendStatus(fiber.StatusUnauthorized)
+    }
+    return c.SendString("Welcome " + payload)
+}

Also applies to: 242-245, 350-353

🤖 Prompt for AI Agents
In paseto/README.md around lines 128-131 (and similarly at 242-245, 350-353),
the README uses direct type assertions like payload :=
pasetoware.FromContext(c).(string) which can panic if the middleware is missing
or returns nil; change the examples to a defensive pattern: retrieve the value
with a comma-ok type assertion (or check for nil), handle the false/nil case by
returning an appropriate error or default response, and only use the asserted
value when safe so the example demonstrates resilient, non-panic-prone
middleware usage.

Comment thread swagger/swagger_test.go
Comment on lines +22 to 23
resp, _ := app.Test(r, fiber.TestConfig{Timeout: 0, FailOnTimeout: false})
return resp
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Don’t ignore app.Test error.

Ignoring the error can mask real failures (router miss, panic). Panic is fine in a helper to keep call sites unchanged.

- resp, _ := app.Test(r, fiber.TestConfig{Timeout: 0, FailOnTimeout: false})
+ resp, err := app.Test(r, fiber.TestConfig{Timeout: 0, FailOnTimeout: false})
+ if err != nil {
+   panic(err)
+ }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
resp, _ := app.Test(r, fiber.TestConfig{Timeout: 0, FailOnTimeout: false})
return resp
resp, err := app.Test(r, fiber.TestConfig{Timeout: 0, FailOnTimeout: false})
if err != nil {
panic(err)
}
return resp
🤖 Prompt for AI Agents
In swagger/swagger_test.go around lines 22 to 23, the helper currently ignores
the error returned by app.Test which can hide router misses or panics; modify
the helper to check the error returned by app.Test and panic if non-nil so
failures surface to tests. Call app.Test, capture (resp, err), if err != nil {
panic(err) }, then return resp.

Comment thread websocket/websocket.go
Comment on lines +116 to 121
return func(c fiber.Ctx) error {
if cfg.Filter != nil && !cfg.Filter(c) {
return c.Next()
}

conn := acquireConn()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Filter logic inverted; requests won’t be skipped when Filter returns true.
Per comment “Filter defines a function to skip middleware”, skip when Filter(c) == true.

Apply:

-    if cfg.Filter != nil && !cfg.Filter(c) {
-        return c.Next()
-    }
+    if cfg.Filter != nil && cfg.Filter(c) {
+        return c.Next()
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return func(c fiber.Ctx) error {
if cfg.Filter != nil && !cfg.Filter(c) {
return c.Next()
}
conn := acquireConn()
return func(c fiber.Ctx) error {
if cfg.Filter != nil && cfg.Filter(c) {
return c.Next()
}
conn := acquireConn()
🤖 Prompt for AI Agents
In websocket/websocket.go around lines 116 to 121, the filter logic is inverted:
currently it calls c.Next() when cfg.Filter(c) is false, but per the comment the
Filter function should skip the middleware when it returns true. Change the
condition to check cfg.Filter != nil && cfg.Filter(c) and return c.Next() in
that case (keep the nil check), so the middleware is skipped when Filter returns
true.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants