Flow: Flow stuck in seemingly infinite loop while initializing.

Created on 16 Mar 2017  路  26Comments  路  Source: facebook/flow

Testing out flow on an existing (large) project, but have only marked one file with /* @flow */, and have excluded npm and jspm module directories:

.flowconfig

[ignore]
./node_modules/
./jspm_packages/

[include]
./src/account/account-constants.js

[libs]

[options]

Here is what I'm seeing:

$ flow
Launching Flow server for C:\Projects\MyProject
Spawned flow server (pid=10124)
Logs will go to C:\Users\Josh\AppData\Local\Temp\flow\CzCzBProjectszBMyProject.log
Launching Flow server for C:\Projects\MyProject
Spawned flow server (pid=9008)
Logs will go to C:\Users\Josh\AppData\Local\Temp\flow\CzCzBProjectszBMyProject.log
Launching Flow server for C:\Projects\MyProject
Spawned flow server (pid=18292)
Logs will go to C:\Users\Josh\AppData\Local\Temp\flow\CzCzBProjectszBMyProject.log
Launching Flow server for C:\Projects\MyProject
Spawned flow server (pid=8232)
Logs will go to C:\Users\Josh\AppData\Local\Temp\flow\CzCzBProjectszBMyProject.log
Launching Flow server for C:\Projects\MyProject
Spawned flow server (pid=8352)
Logs will go to C:\Users\Josh\AppData\Local\Temp\flow\CzCzBProjectszBMyProject.log
flow is still initializing; this can take some time. [merging inference] -

The log is mostly empty:

[2017-03-16 16:24:47] Initializing Server (This might take some time)
[2017-03-16 16:24:47] executable=C:\Users\Josh\AppData\Roaming\npm\node_modules\flow-bin\flow-win64-v0.41.0\flow.exe
[2017-03-16 16:24:47] version=0.41.0
[2017-03-16 16:24:47] Parsing

Not sure how to debug this further.

nontermination / perf

Most helpful comment

reduce is pretty common in javascript, this is a really big deal

any plans to fix this?

All 26 comments

I suspect this is related to the multiflow change regarding rest args introduced in 0.39. I'm seeing something similar. See #3370 and #3443 for a very minimal reproduction.

If you're using ...args without type declarations anywhere in your code, try adding them and see if the problem goes away. If that's it, we should dedupe this to #3370 / #3443 and escalate to @gabelevi.

May be related, may be not - I had this endless spawn loop when I had an invalid .flowconfig that included directories that didn't exist (I had changed the project structure and forgot to change the Flow config file). That too is a bug of sorts - clearly it would be beneficial to stop with an error instead of having this loop. _Meow_.

Hello. Is there a way to determine what causes hanging flow?
We had flow-bin v0.30.
Since some moment running flow just results in infinite initialisation wit high CPU load:

Launching Flow server for /Users/dev/Transient/ws/project
Spawned flow server (pid=66740)
Logs will go to /private/tmp/flow/zSUserszSdevzSTransientzSwszSproject.log
flow is still initializing; this can take some time. [parsing] \

Logs contain:

[2017-04-19 17:02:26] Initializing Server (This might take some time)
[2017-04-19 17:02:26] executable=/Users/dev/Transient/ws/project/node_modules/flow-bin/vendor/flow
[2017-04-19 17:02:26] version=0.30.0
[2017-04-19 17:02:26] Parsing

I have updated to 0.44.1 - same hanging.

How long did you wait? How much source code is there? It appears to be busy parsing, how do you know it hangs? I'm not doubting your report, I just think that would be nice to know.

@lll000111 it used to initialise in a second.
Now it hangs for 5 minutes with overheating CPU until I kill process.
Project is not big - 10k lines of code.

I'm sorry - I guess it was some corruption on my side.
I've erased flow-bin, then fully reinstalled it - now it works properly.

Hey guys,
I also faced this issue, and after few (really) frustrating night, I was able to create a file that always fails (Now we can start debugging 馃憤 !)

Running this on the flow 0.44.2 gets stuck with flow is still initializing; this can take some time. [local inference]

Notice something interesting - it only gets stuck with 4 of these methods -> 3 and it works fine!

// @flow

type Iface = {
  fn1: (arg: string) => Iface,
  fn2: (arg: string) => Iface,
  fn3: (arg: string) => Iface,
  fn4: (arg: string) => Iface
};

function t(): Iface {

    const context = function (...args): any {
    };


    context.fn1 = (arg: string) => {
      return context;
    };

    context.fn2 = (arg: string) => {
      return context;
    };

    context.fn3 = (arg: string) => {
      return context;
    };

    context.fn4 = (arg: string) => {
      return context;
    };

    return context;
}

I forgot to say that i am using OSX.

AND (fun fact) I was able to cause flow's website to stackoverflow with this code!

https://flow.org/try/#0PTAEAEDMBsHsHcBQiAuBPADgU1ASUgIYDGOAvKAN6KiiQB2AjAFygAUBATgOYsDOKHAJZ0uASlCkAfHkIkANNVp0ATC3bc+A4WInT8xLApr0AzGs49Q-ISPFSZBo0oAs5jVa23dDkogC+ANzIkACudEQogrB0oCisoiz6JJTINDRE0fygGXQoWAAeKBK0YRFRMawAdNUWvAmgBHRoKWmggciK6dF5hZX0DMXqltbadtJUrTQcWCghHDE5PShBre2d2d0FKH0qgxaaNjr2E5PTs-MbuVsraWuti1s7JnvuI17H61MzcwubhTc0O5pB69ejOF7DTxHcafUBnH6XJYAtpBdbwi4g5b+IA

A workaround is to use interface:

interface Iface {
  fn1: (arg: string) => Iface,
  fn2: (arg: string) => Iface,
  fn3: (arg: string) => Iface,
  fn4: (arg: string) => Iface
}

Some checks are blowing up in the original version but are optimized with interfaces. Bringing those optimizations back to vanilla object types will take a while.

@nadav-dav We've identified the cause of your issue. I created a separate issue to in #3849, which you can subscribe to if you want to be notified when a fix lands. Thanks for sharing a small repro case! I'm sorry we caused you to burn so much time. The repro made it much easier to find the underlying cause.

Thanks @sam for the response! Rock on:)

@samwgoldman I wonder if you could add some kind of guard-construction, which would detect hanged parsing and log where it failed?

I'm getting the same kind of behavior when type checking this code:

let createRelationshipPaths = (path = "", rels = []) => {
  return rels.length
    ? rels.reduce((acc, [name, nested]) => {
        return [
          ...acc,
          ...createRelationshipPaths(path ? `${path}.${name}` : name, nested)
        ];
      }, path ? [path] : [])
    : [path];
};
let createRelationshipPaths = (path = "", rels = []): string[] => {
// This fixes it --------------------------------------^
  return rels.length
    ? rels.reduce((acc, [name, nested]) => {
        return [
          ...acc,
          ...createRelationshipPaths(path ? `${path}.${name}` : name, nested)
        ];
      }, path ? [path] : [])
    : [path];
};

@JoshMcCullough is your issue gone with 0.47?

Another repro in 0.47 taken from some production code:

https://flow.org/try/#0PTAEAEDMBsHsHcBQiAuBPADgU1ARQK5YBOaA8higJawB2AzqALygDeiooA2gNZZoBcoOiiKUaAcwC6g4aImgAPqBr4AtgCNii0OtixoWAIY1tbDhx58ZIsVOtzx2lRq1KAgkSKG0AHlm2nNU0iAD4AGnZQAF8IqORIfBoAYypaUHEsFAAxSmgUYjos2CIcrGgAEwAKSEoy8oA5Q1UsMNAauoA1Q2hCVpq84kbmugBKVkiiTPwiE378oiGsOgA6SfL8JKxK6tqKtySkvtz5xbHGEPHzUCTaYVAAN27CJjbd8q6erE45waasSUiHBu9BQrwGRAAyjZ5MwAAYAfXhABIWD8Fn8orDAddbqDHp8oQ4Xh4vGhlpQ6CTvJV8YQxgB+B5PLDLABWsDElQA5GEuWNBLSsMgrpRIKBKgBCQWE2xjMxXUCTFDTWZvfZJbFxbFKlVcbEcZaG9p7A4RBWgWEo40NDFW47EGUSKKMFFYZKwcpYACqACUAJIAYVgqgwtDdKEqjvENOZUZGI0xZvMAI4MS4khGiC1CWSqRMAEdCCQo5VC8QBHgi2QKNR6C8WFE5ZFgXdrQxmKR1KysCllrw0HRS1XMxwQIqsKpYPcAlTfP4JBd4LloNdDPg6DgYAhQChYKAABbGRyVdREBAbog7wzqUBL6ArpJeOj7kc4kFg+azl5t1ZYdabbY0ToQRZz8aFxHCV46jOC55SBXEoIqD5nmYMsSG+N4AWxUVxXQbBYDFa1kJwCVGGYLlYC7HsUD5S4FR1GYuENZYgNaS1UTeZ1XXdT1fUDYNQxocNI3AnZOmZeNMRTcwtSuFtQTRRZ21ATtu17ftByIiTsXkj8CiKEo3heDJsntIhCmKUoKjEiojnEz4jnBJTM21KZGM4ZjWNATyzIswy6mktNOAzYVx2VRi0VnZYDAkFB91ARlYXpO1wSi9lOS5AAyPlMVAQQuS5LNkCAA

Folks, in my case (I'm on Windows 10) the issue were resolved by running watchman watch-del-all and then uninstalling watchman (or removing it from the PATH). It seems just weird but anytime I install watchman flow doesn't work.

I was getting the infinite loop problem on Flow 0.56.0. Downgrading to 0.55.0 worked.

I'm getting this flow is still initializing; this can take some time. [merging inference] infinite loop as well running locally on macOS with Flow 0.50. I've tried killing and reinstalling the Flow server and wiping and reinstalling node_modules without success. Here are my logs:

[2017-11-03 09:49:30] Initializing Server (This might take some time)
[2017-11-03 09:49:30] executable=/Users/example/example-app/node_modules/flow-bin/flow-osx-v0.50.0/flow
[2017-11-03 09:49:30] version=0.50.0
[2017-11-03 09:49:30] Parsing
[2017-11-03 09:49:37] Building package heap
[2017-11-03 09:49:37] Loading libraries
[2017-11-03 09:49:40] Resolving dependencies
[2017-11-03 09:49:41] Running local inference
[2017-11-03 09:49:42] Calculating dependencies
[2017-11-03 09:49:42] Merging

Activity Monitor shows Flow is just spinning eating up CPU:
image

But Flow is working in CI running Linux so I don't think it is a problem specific to my code - I wonder if it is specific to the flow-bin/flow-osx-v0.50.0?

Per my last comment, I finally found the file causing the infinite "merging inference" by removing /* @flow */ comments directory by directory, then file by file until finding which file was causing flow to hang. The culprit looked like this:

const getJsonFields = (parsedBody: any, prefix: string = '') =>
  Object.keys(parsedBody).reduce((memo, key) => {
    const value = parsedBody[key]

    if (Array.isArray(value)) {
      return memo
    } else if (value !== null && typeof value === 'object') {
      return [...memo, ...getJsonFields(value, prefix + key + '.')]
    } else {
      return [...memo, prefix + key]
    }
  }, [])

Adding explicit types on the reduce arguments ((memo: Array<string>, key: string) fixed the problem for me:

const getJsonFields = (parsedBody: any, prefix: string = '') =>
  Object.keys(parsedBody).reduce((memo: Array<string>, key: string) => {
    const value = parsedBody[key]

    if (Array.isArray(value)) {
      return memo
    } else if (value !== null && typeof value === 'object') {
      return [...memo, ...getJsonFields(value, prefix + key + '.')]
    } else {
      return [...memo, prefix + key]
    }
  }, [])

I got the same issue as @trevordmiller. Infinite loop on OS X but not in CI running Linux.

How is that even possible ? 馃槀

The culprit was also a reduce function that returned arrays using the spread operator. Fixed by adding types to the arguments of the arrow function.

z$ ./node_modules/.bin/flow version
Flow, a static type checker for JavaScript, version 0.57.3

@jomi-se Try to update to the latest 65 version and run killall flow

I tried out version 0.65.0, flow still gets stuck in the same file on OS X

Please wait. Server is initializing (merged files 215/237 (90.7%)): |

Adding type to all reduce functions arguments in this file fixes it though. I also was able to reproduce it locally with a single file containing

// @flow
const getJsonFields = (parsedBody: any, prefix: string = '') =>
  Object.keys(parsedBody).reduce((memo, key) => {
    const value = parsedBody[key]

    if (Array.isArray(value)) {
      return memo
    } else if (value !== null && typeof value === 'object') {
      return [...memo, ...getJsonFields(value, prefix + key + '.')]
    } else {
      return [...memo, prefix + key]
    }
  }, [])

reduce is pretty common in javascript, this is a really big deal

any plans to fix this?

@sibelius It's not about reduce itself. Just about recursion with it.

Had the same issue, the reason was dist folder with the built project, which was created after 'npm run build'.
[ignore] .*/dist/.*
fixed the problem.

I got the same problem with reduce. Adding type annotations to the functions did the trick.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jamesisaac picture jamesisaac  路  44Comments

gcanti picture gcanti  路  48Comments

STRML picture STRML  路  48Comments

danvk picture danvk  路  73Comments

Gozala picture Gozala  路  54Comments