Skip to content

v0.x: config keys that differ only in case are refused

GTB folds config keys to lower case, so Log.Level and log.level are the same key. Until go/config v0.21.0, a file holding both loaded with one of them chosen at random, and nothing said so (go/config spec 0015). Nothing in a tool's code changes.

What changes

  • A file whose keys collide in case stops the tool. Two keys in one file that differ only in case, at any depth, fail the load with config.ErrKeyCollision. The error names the file and both spellings. This holds when both carry the same value, and for non-string keys that read alike, such as 1 and 1.0. Keys in different files are unaffected: that is precedence, as before.
  • config set edits the key the file has. Setting log.level in a file that spells it Log.Level changes Log.Level in TOML, JSON and HCL files, where it used to add a second key beside it. YAML already did this. A keychain source lands the write on the stored key.
  • config unset removes the key the file has. In TOML, JSON and HCL a mis-cased unset used to remove nothing.

What to check

  • Run any command against each config file a deployment uses, for example <tool> config list --config <file>. A file with a collision fails at load, naming itself and both spellings. Keep one spelling and delete the other. The value the tool used before was whichever won at random, so check which one you meant.
  • A file produced by an earlier mis-cased config set on TOML, JSON or HCL may hold exactly such a pair.