Recently I was testing using Postgres instead of MySQL on a large Rails 6 application. I had created copies of the schemas and removed the MySQL specific attributes from the tables to load in the schema.
All was well at first! I could run
rails db:create and
rails db:schema:load and everything would work perfectly. I could even boot up the app and make a user account.
Time to run the tests!
Out of 3000+ tests, nearly 2/3 failed with the same error...
ArgumentError: string contains null byte
Weird. What even is a null byte? A little research showed me a null byte would/should be an escaped character sequence
\u0000. I tried searching/grepping through the codebase and didn't find that anywhere.
So what the hell is going on?
Well I found another escaped character pattern,
\x00. This specific escaped character sequence is a hexadecimal color, but the double 0 means that the color it should represent has it's bytes set to 0, which is null. So Postgres would see this string coming in and translate it from hexadecimal to escaped unicode which just so happens to turn into
\u0000 and raise the
string contains null byte error.
Grepping the code base revealed this
\x00 pattern used in a few places through model callbacks. This was being used to delineate strings, so I changed the delimiter to
\n\n and now I no longer get the null byte error!
Sometimes taking over an existing code base... you find awfully strange things!