invalid value for parameter “TimeZone”

While working on standing up a Rails app I ran into a pretty weird error that really had me scratching my head.

[mike@longshot identity-idp]$ rake db:create
PG::InvalidParameterValue: ERROR:  invalid value for parameter "TimeZone": "UTC"
: SET time zone 'UTC'
Couldn't create database for {"pool"=>5, "timeout"=>5000, "host"=>"localhost", "adapter"=>"postgresql", "encoding"=>"utf8", "database"=>"upaya_development", "port"=>5432}
rake aborted!
ActiveRecord::StatementInvalid: PG::InvalidParameterValue: ERROR:  invalid value for parameter "TimeZone": "UTC"
: SET time zone 'UTC'

PG::InvalidParameterValue: ERROR:  invalid value for parameter "TimeZone": "UTC"

Tasks: TOP => db:create
(See full trace by running task with --trace)

The output of timedatectl status looked OK, but just to be sure, I updated them to EDT. No difference. When I tried rake db:migrate I got a far more instructive error:

[mike@longshot identity-idp]$ rake db:migrate
rake aborted!
ArgumentError: Invalid Timezone: UTC
/home/mike/projects/identity-idp/config/environment.rb:5:in `<top (required)>'
TZInfo::InvalidTimezoneIdentifier: Expected 44 bytes reading '/usr/share/zoneinfo/UTC', but got 0 bytes
/home/mike/projects/identity-idp/config/environment.rb:5:in `<top (required)>'
TZInfo::InvalidZoneinfoFile: Expected 44 bytes reading '/usr/share/zoneinfo/UTC', but got 0 bytes
/home/mike/projects/identity-idp/config/environment.rb:5:in `<top (required)>'
Tasks: TOP => log => environment
(See full trace by running task with --trace)

/usr/share/zoneinfo/UTC is 0 bytes? A quick looks shows it to be true, and the package that supplied this file is tzdata.

[mike@longshot identity-idp]$ cat /usr/share/zoneinfo/UTC 
[mike@longshot identity-idp]$ ls -l /usr/share/zoneinfo/UTC 
-rw-r--r-- 6 root root 0 Jul 26 18:01 /usr/share/zoneinfo/UTC
[mike@longshot identity-idp]$ pacman -Qo /usr/share/zoneinfo/UTC
/usr/share/zoneinfo/UTC is owned by tzdata 2017b-1

That doesn’t seem right, let’s reinstall…

[mike@longshot identity-idp]$ sudo pacman -S tzdata
warning: tzdata-2017b-1 is up to date -- reinstalling
resolving dependencies...
looking for conflicting packages...

Packages (1) tzdata-2017b-1

Total Installed Size:  1.81 MiB
Net Upgrade Size:      0.00 MiB

:: Proceed with installation? [Y/n] y
(1/1) checking keys in keyring                                               [###########################################] 100%
(1/1) checking package integrity                                             [###########################################] 100%
(1/1) loading package files                                                  [###########################################] 100%
(1/1) checking for file conflicts                                            [###########################################] 100%
(1/1) checking available disk space                                          [###########################################] 100%
:: Processing package changes...
(1/1) reinstalling tzdata                                                    [###########################################] 100%
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate...
[mike@longshot identity-idp]$ ls -l /usr/share/zoneinfo/UTC 
-rw-r--r-- 6 root root 127 Mar 24 12:38 /usr/share/zoneinfo/UTC
[mike@longshot identity-idp]$ cat /usr/share/zoneinfo/UTC 
TZif2UTCTZif2�UTC
UTC0

After that, creating and migrating worked again without problems. I’m not sure what happened there, but hopefully this will prevent people (or future me) wasting a bunch more time on it.

Advertisements

Rails integer handling

Well it certainly is the case that you learn something new every day. After digging into some confusion around how Rails chooses its data types I ended up turning to the API docs.  From the API docs:

:limit – Requests a maximum column length. This is number of characters for :string and :text columns and number of bytes for :binary and :integer columns.

:limit => 11 would give us 11 characters in a string column, but I was trying to apply it to an integer.  As they said in the docs, when you use :limit with an integer it means the number of bytes. So, for the sake of my own mental clarity here is what you should get when you use the :limit option:

:limit => 1 TINYINT 1 byte -128 to 127
:limit => 2 SMALLINT 2 bytes -32768 to +32767
:limit => 3 MEDIUMINT 3 bytes -8388608 to 8388607
:limit => 4 INT 4 bytes -2147483648 to +2147483647
:limit => 8 BIGINT 8 bytes -9223372036854775808 to 9223372036854775807

I say “should” above because Rails will take the value you give it and map that as best it can to whatever the actual database you are using can provide. So for MySQL it will give you a bigint for any :limit value between 5 and 8. One strange thing is that :limit => 11 maps to a 4 byte int(11) in MySQL. Not sure what thats about. For values that fall outside those, well, I guess I’ll figure that out another day.

Bundle mania

I ended up using Heroku’s bundles feature a fair bit today. For those who have not played with this yet, a bundle is essentially a zip/tar file containing all the code from your application along with a dump  of your database. From the help file:

bundles                      # list bundles for the app
bundles:capture [<bundle>]   # capture a bundle of the app’s code and data
bundles:download             # download most recent app bundle as a tarball
bundles:download <bundle>    # download the named bundle
bundles:animate <bundle>     # animate a bundle into a new app
bundles:destroy <bundle>     # destroy the named bundle

In general its pretty intuitive. The commands do what you expect; “bundles:capture” captures a bundle, while “bundles:download mybundle” downloads the bundle named mybundle. With my expectations set by using the other commands I tried out bundles:animate

mike@sleepycat:~/projects/myapp$ heroku bundles
2010-03-16        complete 03/17/2010 14:25
mike@sleepycat:~/projects/myapp$ heroku bundles:animate 2010-03-16
Animated myapp 2010-03-16 into http://myapp-2010-03-16.heroku.com/ | git@heroku.com:myapp-2010-03-16.git

Given the description “animate a bundle into a new app” I was expecting a fully functional copy of my application waiting for me at that new address, based on the code and the database dump contained in the bundle. Instead I get:

mike@sleepycat:~/projects/myapp$ heroku console –app myapp-2010-03-16
!   myapp-2010-03-16 has an empty code repository. Push and try again.

When I log in and look at my account, sure enough the repository is empty and even more surprising:

Data size

0 Bytes in 0 tables

So if it does not load any of the code from my bundle, and doesn’t use the database dump to create a database, how does this differ from creating a new app?