Skip to content

Bug: empty-string env vars coerced to number 0 in ConfigService, silently overriding defaults #455

@lonix

Description

@lonix

Problem

In src/services/config-service.ts the get() method falls back to environment variables when a key is absent from the cache and the database. The numeric-coercion branch has an off-by-one:

// config-service.ts ~line 333
if (!isNaN(Number(envValue))) {
  const numValue = Number(envValue);
  this.cache.set(key, numValue);
  return numValue;
}

Number("") evaluates to 0, and isNaN(0) is false. So any env var that is set to an empty string is cached as the number 0 instead of being treated as absent. This bypasses every defaultValue argument callers pass to getNumber() and getBoolean().

Reproduction scenario

  1. An operator sets SOME_KEY= (empty value) in their .env — possibly a leftover placeholder.
  2. configService.getNumber("SOME_KEY", 60) silently returns 0 instead of 60.
  3. Features depending on that number (cooldowns, max lengths, retention periods, etc.) behave with a value of 0, which can mean "unlimited" or "zero seconds" depending on the callsite.

Suggested fix

Guard with an explicit emptiness check before trying numeric conversion:

const envValue = process.env[key];
if (envValue !== undefined && envValue.trim() !== "") {
  if (envValue === "true" || envValue === "false") {
    const boolValue = envValue === "true";
    this.cache.set(key, boolValue);
    return boolValue;
  }
  const numValue = Number(envValue);
  if (!isNaN(numValue)) {
    this.cache.set(key, numValue);
    return numValue;
  }
  this.cache.set(key, envValue);
  return envValue;
}

This makes an empty env var behave as if the key were absent, so defaultValue arguments are correctly honoured.

Affected file

src/services/config-service.ts lines 326–341 (the env-var fallback branch inside get())

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