69

I have been stuck on this error in my project when I add "proxy": "http://localhost:6000" in my package.json.

This is the error response after yarn start.

Invalid options object. Dev Server has been initialized using an options object that does not match the API schema.

  • options.allowedHosts[0] should be a non-empty string. error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

But everything is fine when I remove the "proxy": "http://localhost:6000".

This is on my package.json:

{
  "name": "client",
  "version": "0.1.0",
  "private": true, 
  "dependencies": {
    "@material-ui/core": "^4.12.3",
    "@testing-library/jest-dom": "^5.16.1",
    "@testing-library/react": "^12.1.2",
    "@testing-library/user-event": "^13.5.0",
    "axios": "^0.24.0",
    "moment": "^2.29.1",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-file-base64": "^1.0.3",
    "react-redux": "^7.2.6",
    "react-scripts": "5.0.0",
    "redux": "^4.1.2",
    "redux-thunk": "^2.4.1",
    "web-vitals": "^2.1.2"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "proxy": "http://localhost:6000"
}
captainrad
  • 3,760
  • 16
  • 41
  • 74
Pusoy
  • 828
  • 1
  • 8
  • 15
  • 1
    If everything is fine if you remove it, why not remove it? – Evert Dec 16 '21 at 06:15
  • 3
    Because it may be needed? I need it to proxy my api requests to my backend in my react app. But yeah i am looking for solution to this too – Adventune Dec 16 '21 at 07:36
  • 3
    This https://githubmemory.com/repo/facebook/create-react-app/issues/11762 article has the reason but does not yet have a solution – Adventune Dec 16 '21 at 07:41

20 Answers20

68

Here is a workaround. Delete "proxy": "http://localhost:6000". Install package http-proxy-middleware with command npm install http-proxy-middleware --save. Create a file setupProxy.js inside your src folder or the root of your folder. Add these lines inside:

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    '/api',
    createProxyMiddleware({
      target: 'http://localhost:6000',
      changeOrigin: true,
    })
  );
};

Now, run your app. It should work.

noam aghai
  • 1,364
  • 3
  • 18
  • 30
josipat
  • 720
  • 4
  • 2
  • Thank you for the workaround @josipat. It seems that using `/` for the context (the route matching value) causes some issues. Unless I am missing something, you will have to use a non-root path like you suggest above (/api). When trying to emulate what I was using with the `proxy` value in my _package.json_ file, I receive a client error: `domain option is required`. – dmarr Dec 27 '21 at 19:11
  • 1
    Also, to point out, you may want to do: `app.use(createProxyMiddleware('/api', { ...` instead to receive proper logging from the middleware. – dmarr Dec 28 '21 at 14:54
  • This worked for me. I upgraded webpack and node, removed proxy from my package.json, then upgraded my existing api calls to route to /api. – Syllith Jan 22 '22 at 04:52
  • 1
    my app still runs on port 3000 instead of 8000 – damanpreet singh Mar 03 '22 at 15:08
  • 1
    This may be a silly question, but when we create this file then re-run our react app, when we make our fetch call, how does the proxy really work? How does it automatically register when we run the dev server without needing to import it anywhere? – Avi Dave Mar 15 '22 at 21:29
  • I see the same "Invalid options object..." error message but ONLY when I attempt to run offline. When I am online everything works fine. Why is that? – Jason Mar 31 '22 at 21:47
31

The other solutions did not work for me so here's what I found:

This seems to be a CRA bug (security feature?) where allowedHosts gets set to [undefined] because prepareUrls doesn't set lanUrlForConfig when both a host and a proxy are specified. The relevant CRA GitHub issue is here.

If appropriate in your use case (read here to learn more), this can be avoided by creating a .env file and adding DANGEROUSLY_DISABLE_HOST_CHECK=true to it or trying DANGEROUSLY_DISABLE_HOST_CHECK=true yarn start.

acdcjunior
  • 132,397
  • 37
  • 331
  • 304
NullDefault
  • 311
  • 3
  • 4
23

Setting "allowedHosts" as a property in package.json didn't work for me. I had to wrap it in an options property:

"options": {
    "allowedHosts": ["localhost", ".localhost"],
    "proxy": "https://localhost:3386/"
  }

After that, npm start did the trick without having to re-install modules.

Update: I did some additional research based on some of the comments and other answers (notably Anjul's). I wasn't able to find documentation supporting an "options" entry in package.json; however, it looks to me like it may be there as a side-effect of using Webpack.

Bill Horvath
  • 1,336
  • 9
  • 24
17

A quick solution is to downgrade your webpack version using react-scripts

In the package.json file of your react-app, change the react-scripts version.

Replace

"react-scripts": "5.*", 

To

"react-scripts": "4.0.3",

Remove node_modules and install the packages again for your react app.

Anjul Tyagi
  • 410
  • 3
  • 11
9

Run npm audit fix --force And while still connected to the internet Run npm start

Should work fine

Mo.
  • 26,306
  • 36
  • 159
  • 225
6

For me removing package-lock.json and node_modules folder - then running npm i solved the problem.

asiop
  • 707
  • 4
  • 11
5

Reverting back to an older version of node worked for me. First of all clear npm's cache and install older version of node.

    > sudo npm cache clean -f
    > sudo npm install -g n
    > sudo n <version>

Latest version 18 was not working for me; version 14.8.2 works for me as I was using this version previously. You can try with any version below 18

apex
  • 791
  • 9
  • 23
4

I just debugged the issue in JS Debugger.

Node v18 changed os.networkInterfaces() family:

v18.0.0
The family property now returns a number instead of a string.

This is throwing off address module used by react-scripts which checks family against "IPv4"

marcopolo
  • 1,963
  • 4
  • 18
  • 31
2

I solved the problem with the http-proxy-middleware solution as others. But to get it working properly, I had to close down my VPN. Same answer as Saeed Kolivand has above. =)

ouflak
  • 2,458
  • 10
  • 44
  • 49
  • For me, no change is required. Only disabling the VPN did the job. Tried everything mentioned here... until I read this answer and found VPN is the culprit. – skafle Jul 14 '23 at 17:00
2

To overcome this problem what you should do is that You just have to be connected to internet when you run npm start

  • This helped me, my issue was I was on the "CoxWifi" so some internet worked, but this must have blocked whatever npm needs....connecting to the proper wifi fixed it. – sirclesam Nov 24 '22 at 04:27
1

this error with Node version 18.0.0 , I try with version Node 16.15.0 it works fine

1

So my team had the same issue, with the same error of options.allowedHosts[0] should be a non-empty string. The solution we outline below is a very specific error and most likely does not pertain to many people.

In our case, the allowedHosts[0] variable was undefined and we traced the allowedHosts[0] variable to be equal to allowedHost in node_modules\react-scripts\config\webpackDevServer.config.js.

module.exports = function (proxy, allowedHost) {
  const disableFirewall =
    !proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true';
  return {
    // WebpackDevServer 2.4.3 introduced a security fix that prevents remote
    // websites from potentially accessing local content through DNS rebinding:
    // https://github.com/webpack/webpack-dev-server/issues/887
    // https://medium.com/webpack/webpack-dev-server-middleware-security-issues-1489d950874a
    // However, it made several existing use cases such as development in cloud
    // environment or subdomains in development significantly more complicated:
    // https://github.com/facebook/create-react-app/issues/2271
    // https://github.com/facebook/create-react-app/issues/2233
    // While we're investigating better solutions, for now we will take a
    // compromise. Since our WDS configuration only serves files in the `public`
    // folder we won't consider accessing them a vulnerability. However, if you
    // use the `proxy` feature, it gets more dangerous because it can expose
    // remote code execution vulnerabilities in backends like Django and Rails.
    // So we will disable the host check normally, but enable it if you have
    // specified the `proxy` setting. Finally, we let you override it if you
    // really know what you're doing with a special environment variable.
    // Note: ["localhost", ".localhost"] will support subdomains - but we might
    // want to allow setting the allowedHosts manually for more complex setups
    allowedHosts: disableFirewall ? 'all' : [allowedHost],

urls.lanUrlForConfig is passed in to the config file from node_modules\react-scripts\scripts\start.js to allowedHost.

const createDevServerConfig = require('../config/webpackDevServer.config');
...
createDevServerConfig(proxyConfig, urls.lanUrlForConfig)

urls.lanUrlForCofig is produced by the prepareUrls function in node_modules\react-dev-utils\WebpackDevServerUtils.js.

const urls = prepareUrls(
  protocol,
  HOST,
  port,
  paths.publicUrlOrPath.slice(0, -1)
);

In the prepareUrls function, urls.lanUrlForConfig is set as undefined in the case that the computer's IPv4 address is non-private as seen below:

try {
  // This can only return an IPv4 address
  lanUrlForConfig = address.ip();
  if (lanUrlForConfig) {
    // Check if the address is a private ip
    // https://en.wikipedia.org/wiki/Private_network#Private_IPv4_address_spaces
    if (
      /^10[.]|^172[.](1[6-9]|2[0-9]|3[0-1])[.]|^192[.]168[.]/.test(
        lanUrlForConfig
      )
    ) {
      // Address is private, format it for later use
      lanUrlForTerminal = prettyPrintUrl(lanUrlForConfig);
    } else {
      // Address is not private, so we will discard it
      lanUrlForConfig = undefined;
    }
  }
} catch (_e) {
  // ignored
}

So in the end, we determined that the reason why we were having the error was because the ip address that we being pulled from the machine was non-private due to some ethernet cable configurations (We were getting a 169. address, an APIPA one, that was because the machine couldn't reach a DHCP server). This caused the urls.lanUrlForConfig to be undefined, which would ultimately get passed all the way down to the allowedHosts[0] variable and cause the error.

Fixing the inability of not being able to connect to the DHCP server is another issue itself, but as a hotfix for development purposes only, we added a DANGEROUSLY_DISABLE_HOST_CHECK=true into our .env file and it worked fine after restarting the development server. Setting "allowedHosts": "all" in our package.json was another solution.

Daniel Ji
  • 11
  • 1
0

I had the same problem and josipat's answer worked for me, except I needed to install it as a development dependency. The solution where one saves the following code to src/setUpProxy.js originates from Create React App.

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function(app) {
  app.use(
    '/api',
    createProxyMiddleware({
      target: 'http://localhost:5000',
      changeOrigin: true,
    })
  );
};

Kiira
  • 46
  • 7
0

I got this error only when switching to Node 18.0.0 with nvm. Getting rid of "proxy":"http://localhost:5000" fixes it, but it's not an option for me and I'd like to avoid the proxy middleware on server. If you switch to a previous Node version like 17.0.0 it works fine. I think that could be a better option until CRA team does not address the issue.

Cesare Polonara
  • 3,473
  • 1
  • 9
  • 19
0

For 5.0.1 react-scripts the bug has not been reproduced, but error occurs in 5.0.0. I guess you could use 5.0.1 to solve this problem

Kirill
  • 31
  • 5
0

If you add or remove "proxy": "http://localhost:6000" in package.json, then remove node_modules and reinstall it. This works for me.

csgeek
  • 711
  • 6
  • 15
0

Faced the same issue several times but finally I found a solution!!

I solved this problem by adding "allowedHosts": "all" to my package.json file

Example:

"allowedHosts": "all",
"proxy": "http://localhost:3001/api",
"name": "simple-blog",
"version": "0.1.0",
"private": true,
"dependencies": {
  "@testing-library/jest-dom": "^5.1

Another solution is by adding DANGEROUSLY_DISABLE_HOST_CHECK=true to your .env file it solves the problem too.

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Sep 07 '22 at 19:24
0

if you are using webpack.config.js different..

const { createProxyMiddleware } = require('http-proxy-middleware'); 
module.exports = {
plugins: [
    new createProxyMiddleware({
        target: 'http://localhost:6000',
        changeOrigin: true,
      })
],
}
Ali
  • 305
  • 3
  • 14
0

i have faced the same problem but without doing any other code or structural manipulation, I first created a new react-app. I just installed all the dependencies which are found in the json file of the one which is not working and I deleted the node module , the backagelock.json file from the react-app which is not working. I removed all the content in json file and copied and pasted all things from the new react-app json file to the old json file and after saving I did npm install on the terminal and it worked.

Rediat
  • 11
  • 3
-3

I had the same issue, You can add "allowedHosts": "all" after "proxy": "https://yourdomain" in your package.json. hopefully it solves your problem.

update: the problem was with the company VPN. When I disconnect the VPN, it works normally.