Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improving the debug-ability of Unable to find next-intl locale because the middleware didn't run on this request. #716

Closed
RaenonX opened this issue Dec 11, 2023 · 4 comments · Fixed by #742
Labels
enhancement New feature or request unconfirmed Needs triage.

Comments

@RaenonX
Copy link

RaenonX commented Dec 11, 2023

Is your feature request related to a problem? Please describe.

Sort of? Because I type the locale, the sample code provided at the very top of this doc page doesn't work for me, as matcher accepts const string only. This brings me to use this middleware config:

export const config = {
  // Skip all paths that should not be internationalized. This example skips the
  // folders "api", "_next" and all files with an extension (e.g. favicon.ico)
  matcher: ['/((?!api|account|_next|.*\\..*).*)'],
};

However, I am seeing tons of Error: Unable to find next-intl locale because the middleware didn't run on this request. See https://next-intl-docs.vercel.app/docs/routing/middleware#unable-to-find-locale errors. Since the error message doesn't have the request origin included, I don't really know what request causes this error.

Describe the solution you'd like

Error message be like Unable to find next-intl locale because the middleware didn't run on the request originated from some/path.

Describe alternatives you've considered

N/A

Additional Note

This happens in production build only, and I really have no idea what request triggered this error.
The log message doesn't give me useful information as well, unfortunately.

2|Pokemon.Sleep.UI  | 2023-12-11T14:22:27: Error: Unable to find `next-intl` locale because the middleware didn't run on this request. See https://next-intl-docs.vercel.app/docs/routing/middleware#unable-to-find-locale
2|Pokemon.Sleep.UI  |     at apply (C:\Users\Spinach\Documents\App\Deployments\Pokemon-Sleep-UI\20231210.9\.next\server\chunks\7980.js:1:60371)
2|Pokemon.Sleep.UI  |     at C:\Users\Spinach\Documents\App\Deployments\Pokemon-Sleep-UI\20231210.9\node_modules\next\dist\compiled\next-server\webpack:\next\dist\compiled\react\cjs\react.shared-subset.production.min.js:22:500
2|Pokemon.Sleep.UI  |     at u (C:\Users\Spinach\Documents\App\Deployments\Pokemon-Sleep-UI\20231210.9\.next\server\chunks\7980.js:1:60656)
2|Pokemon.Sleep.UI  |     at i (C:\Users\Spinach\Documents\App\Deployments\Pokemon-Sleep-UI\20231210.9\.next\server\chunks\1674.js:1:146011)
2|Pokemon.Sleep.UI  |     at b (C:\Users\Spinach\Documents\App\Deployments\Pokemon-Sleep-UI\20231210.9\.next\server\chunks\3878.js:9:1136)
2|Pokemon.Sleep.UI  |     at Q (C:\Users\Spinach\Documents\App\Deployments\Pokemon-Sleep-UI\20231210.9\node_modules\next\dist\compiled\next-server\webpack:\next\dist\compiled\react-server-dom-webpack\cjs\react-server-dom-webpack-server.edge.production.min.js:42:209)
2|Pokemon.Sleep.UI  |     at C:\Users\Spinach\Documents\App\Deployments\Pokemon-Sleep-UI\20231210.9\node_modules\next\dist\compiled\next-server\webpack:\next\dist\compiled\react-server-dom-webpack\cjs\react-server-dom-webpack-server.edge.production.min.js:47:294
2|Pokemon.Sleep.UI  |     at Array.K (C:\Users\Spinach\Documents\App\Deployments\Pokemon-Sleep-UI\20231210.9\node_modules\next\dist\compiled\next-server\webpack:\next\dist\compiled\react-server-dom-webpack\cjs\react-server-dom-webpack-server.edge.production.min.js:53:250)
2|Pokemon.Sleep.UI  |     at stringify (<anonymous>)
2|Pokemon.Sleep.UI  |     at eE (C:\Users\Spinach\Documents\App\Deployments\Pokemon-Sleep-UI\20231210.9\node_modules\next\dist\compiled\next-server\webpack:\next\dist\compiled\react-server-dom-webpack\cjs\react-server-dom-webpack-server.edge.production.min.js:57:54)
@RaenonX RaenonX added enhancement New feature or request unconfirmed Needs triage. labels Dec 11, 2023
@Maciej916
Copy link

Maciej916 commented Dec 11, 2023

I'm encountering a similar issue while using the localePrefix 'as-needed' alongside the same matcher. For instance, when there's a missing image, console errors arise, and addressing this situation is imperative. Additionally, I've observed a related problem—storing the favicon.ico in a location other than /favicon.ico. This leads to Google Chrome attempting to retrieve the favicon.ico each time I open the page, resulting in an error. While one workaround is creating a different matcher, it's suboptimal as users might open random images (/random.png) that, while ignored by the matcher, trigger errors consistently. Hence, a more comprehensive solution or improvement is warranted. Edit: Another example is that I store favicon.ico in a different location than /favicon.ico, and every time I open the page in Google Chrome, it tries to retrieve the favicon.ico, causing an error. I can avoid this by creating a different matcher, but that's not ideal because a user can open a random image (/random.png), and since it is ignored by the matcher, it will throw an error each time.

@amannn
Copy link
Owner

amannn commented Dec 12, 2023

@RaenonX I'm unfortunately not aware of anything next-intl could do to improve the debugging experience here. E.g. there's no way next-intl could output a pathname for example, because this information is not available by the time a locale is read. The only way to get a hold of a pathname in Server Components, is to attach it in a middleware—however, this is the problem that you're having: the middleware doesn't run on this request.

The troubleshooting section for this error contains all the cases I've seen users run into so far. This is the best resource to help you fix the error. Maybe you also have some luck by checking your CDN logs for 500 response codes so you can get a hold of the request URL.

For instance, when there's a missing image, console errors arise, and addressing this situation is imperative.

@Maciej916 That's why the troubleshooting guide recommends to validate your incoming locale. That should fix this error.


Generally, next-intl recommends this middleware config:

import createMiddleware from 'next-intl/middleware';
 
export default createMiddleware({
  // A list of all locales that are supported
  locales: ['en', 'de'],
 
  // Used when no locale matches
  defaultLocale: 'en'
});
 
export const config = {
  // Match only internationalized pathnames
  matcher: ['/', '/(de|en)/:path*']
};

This will help you to avoid this error. If you switch to localePrefix: 'as-needed' you need to be more careful—as mentioned in the docs.

I'm closing this issue as it's unfortunately not actionable.

@amannn amannn closed this as completed Dec 12, 2023
@RaenonX
Copy link
Author

RaenonX commented Dec 12, 2023

Sad but understandable, thanks for the explanation, and great tips on checking CDN logs ngl!

amannn added a commit that referenced this issue Dec 21, 2023
…and update docs to suggest validating the locale in `i18n.ts` (#742)

Users are currently struggling with errors that are caused by these two
scenarios:
1. An invalid locale was passed to `next-intl` APIs (e.g.
[#736](#736))
2. No locale is available during rendering (e.g.
[#716](#716))

**tldr:**
1. We now suggest to validate the incoming `locale` in
[`i18n.ts`](https://next-intl-docs.vercel.app/docs/usage/configuration#i18nts).
This change is recommended to all users.
2. `next-intl` will call the `notFound()` function when the middleware
didn't run on a localized request and `next-intl` APIs are used during
rendering. Previously this would throw an error, therefore this is only
relevant for you in case you've encountered [the corresponding
error](https://next-intl-docs.vercel.app/docs/routing/middleware#unable-to-find-locale).
Make sure you provide a relevant [`not-found`
page](https://next-intl-docs.vercel.app/docs/environments/error-files#not-foundjs)
that can be rendered in this case.

---

**Handling invalid locales**

Users run into this error because the locale wasn't sufficiently
validated. This is in practice quite hard because we currently educate
in the docs that this should happen in [the root
layout](https://next-intl-docs.vercel.app/docs/getting-started/app-router#applocalelayouttsx),
but due to the parallel rendering capabilities of Next.js, potentially a
page or `generateMetadata` runs first.

Therefore moving this validation to a more central place seems
necessary. Due to this, the docs will now suggest validating the locale
in `i18n.ts`. By doing this, we can catch erroneous locale arguments in
a single place before e.g. importing JSON files.

The only edge case is if an app uses no APIs of `next-intl` in Server
Components at all and therefore `i18n.ts` doesn't run. This should be a
very rare case though as even `NextIntlClientProvider` will call
`i18n.ts`. The only case to run into this is if you're using
`NextIntlClientProvider` in a Client Component and delegate all i18n
handling to Client Components too. If you have such an app, `i18n.ts`
will not be invoked and you should validate the `locale` before passing
it to `NextIntlClientProvider`.

**Handling missing locales**

This warning is probably one of the most annoying errors that users
currently run into:

```
Unable to find next-intl locale because the middleware didn't run on this request.
```

The various causes of this error are outlined in [the
docs](https://next-intl-docs.vercel.app/docs/routing/middleware#unable-to-find-locale).

Some of these cases should simply be 404s (e.g. when your middleware
matcher doesn't match `/unknown.txt`), while others require a fix in the
matcher (e.g. considering `/users/jane.doe` when using `localePrefix:
'as-necessary'`).

My assumption is that many of these errors are false positives that are
caused by the `[locale]` segment acting as a catch-all. As a result, a
500 error is encountered instead of 404s. Due to this, this PR will
downgrade the previous error to a dev-only warning and will invoke the
`notFound()` function. This should help in the majority of cases. Note
that you should define [a `not-found`
file](https://next-intl-docs.vercel.app/docs/environments/error-files#not-foundjs)
to handle this case.

I think this change is a good idea because if you're using
`unstable_setRequestLocale` and you have a misconfigured middleware
matcher, you can provide any kind of string to `next-intl` (also
`unknown.txt`) and not run into this error. Therefore it only affects
users with dynamic rendering. Validating the locale in `i18n.ts` is the
solution to either case (see above). Also in case something like
[`routeParams`](#663) gets
added to Next.js, the current warning will be gone entirely—therefore
tackling it from a different direction is likely a good idea.

The false negatives of this should hopefully be rather small as we
consistently point out that you need to adapt your middleware matcher
when switching the `localePrefix` to anything other than `always`.
Dev-only warnings should help to get further information for these
requests.

---

Closes #736
Closes #716
Closes #446
@amannn
Copy link
Owner

amannn commented Dec 21, 2023

There was an update to this in #742: next-intl will now call notFound() for these cases and therefore no error will be thrown anymore. A dev-only warning will still be printed though. Please still make sure that your middleware matcher is set up correctly. Have a look at the PR for details!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request unconfirmed Needs triage.
Projects
None yet
3 participants