What Mac OS’s case-insensitive filenames teaches us

Paul Jensen
2 min readNov 9, 2019

--

I was writing some code for a Node.js project on my MacBook. I wrote the code, the tests passed, so I commited it to GitHub and the build pipeline did its checks.

One of the checks failed — the tests on CircleIC failed. I took a look, and stumbled across this unexpected error:

FAIL  __****s__/controllers/users.****.js
● Test suite failed to run

Cannot find module './admin' from 'index.js'

However, Jest was able to find:
'./users.js'

You might want to include a file extension in your import, or update your 'moduleFileExtensions', which is currently ['js', 'json', 'jsx', 'ts', 'tsx', 'node'].

See https://jestjs.io/docs/en/configuration#modulefileextensions-array-string

However, Jest was able to find:
'../../index.js'

I initially didn’t know what the cause was. The tests passed on my machine, so I did that thing that Einstein defines as insanity — I ran the tests on CircleCI again, hoping for a different outcome.

The tests failed again. The same outcome, with the same error message.

I dug in a little more. I noticed one important detail:

Cannot find module './admin' from 'index.js'

I knew what line of code that was in the project, but then I realised something — the file it was referring to was named Admin.js, with a capital at the start.

This was the cause of the error. Changing the require path to ‘./Admin’ fixed the issue, and the tests passed on CircleCI.

So why did they fail?

The tests failed on CircleCI because the operating system used to run the tests was Linux, and in Linux the file system is case sensitive. On Mac OS, the file system is case insensitive. This was why the tests passed on my MacBook but not on CircleCI, even though the code was the same.

What it teaches us

That example reminded me of one of the fundamental learnings that I’ve had in working in IT over the past decade — if the expected inputs and factors for 2 scenarios are the same, then the outcomes of those scenarios should be the same. This is why you want to make staging and production environments as identical as possible, why you try to standardise implementations of various systems, why you ask customers what device and operating system they were using when trying to replicate a bug that they encountered.

In short, it is the scientific method that is being applied.

Whenever you encounter a bug or an unexpected outcome, try to identify all the factors involved, and look for the differences — that can help to explain the cause.

--

--

Paul Jensen

Founder of Anephenix, and author of “Cross Platform Desktop Applications”.