Skip to content

fix(config): env loader drops falsy values — COCO_VERBOSE=false and friends cannot override lower config layers #1635

Description

@gfargo

loadEnvConfig discards any parsed env value that is falsy, so boolean env overrides to false never apply. Env vars are the highest-precedence config layer below argv, but they can only turn booleans ON, never OFF. Found in v0.81.0 (main @ 6de37e0).

Failure scenario

  • ~/.gitconfig [coco] sets verbose = true (or conventionalCommits = true, includeBranchName = true, openInEditor = true).
  • CI job runs COCO_VERBOSE=false coco commit expecting quiet logs → parseEnvValue coerces 'false' to boolean false, then the loader drops it, and the gitconfig true wins. Same for COCO_CONVENTIONAL_COMMITS=false, etc. Documented precedence (env > git config, src/lib/config/utils/loadConfig.ts:45-53) is violated for every boolean-off override.

Root cause

src/lib/config/services/env.ts:88-90:

if (key === 'service' || !envValue) {
  return
}

!envValue was presumably meant to skip empty strings, but after parseEnvValue has already converted 'false'false (env.ts:225-226) it also drops legitimate boolean false (and would drop a numeric 0 for any future numeric top-level key).

Affected files

  • src/lib/config/services/env.ts (defect)
  • src/lib/config/utils/loadConfig.ts (precedence contract this breaks)

Suggested fix

Replace the falsy check with an explicit empty check: if (key === 'service' || envValue === undefined || envValue === '') return. parseEnvValue already returns undefined for unset vars, so false/0 flow through and override lower layers as documented.

Testing notes

Existing env tests only assert truthy overrides. Regression test: config layer with verbose: true + process.env.COCO_VERBOSE = 'false'loadEnvConfig result has verbose === false (and active: true in the returnSource variant).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions