Issue with Nested Environment Variables in Effect Typescript Library Configuration

I am not sure if this is intended behaviour (if you want to skip ahead: https://effect.website/play#e9317240a36c):

I have this following implementation

export const ConfigProviderLive = Layer.unwrapEffect(
  Effect.gen(function* () {
    if (process.env.NODE_ENV !== 'production') {
      return yield* PlatformConfigProvider.fromDotEnv('.env').pipe(
        Effect.map(Layer.setConfigProvider),
      );
    }
    return Layer.setConfigProvider(ConfigProvider.fromEnv());
  }),
);


And even with PlatformConfigProvider.layerDotEnvAdd or PlatformConfigProvider.layerDotEnv I keep getting the message:

Error: (Missing data at QUEUE_A.CONCURRENCY: "Expected QUEUE_ACONCURRENCY to exist in the provided map")

I want to read from a .env file when not in production. In production ENVs are attached by kubernetes. The following works but only because fromEnv uses process.env in the NodeRuntime which dotenv fills.

export const ConfigProviderLive = Layer.unwrapEffect(
  Effect.gen(function* () {
    if (process.env.NODE_ENV !== 'production') {
      const dotenv = yield* Effect.promise(() => import('dotenv'));
      dotenv.config();
    }
    return Layer.setConfigProvider(ConfigProvider.fromEnv());
  }),
);


However, with what Effect provides, I expect that I don't need the dotenv (at least not explicitly). What's weird is that when I patch Effect and I log the key / value read from parseDotEnv, I get:

DOTENV { key: 'QUEUE_NAMES', value: 'A' }
DOTENV { key: 'QUEUE_A_CONCURRENCY', value: '123' }

so it reads the values correctly, but it does not find them afterwards, because I think it uses fromJson and consequently uses const hiddenDelimiter = "\ufeff" as a path delimiter.
It correctly finds QUEUE_NAMES with a single underscore at the root level, but the nested QUEUE_A_CONCURRENCY is not found. Here is the example: https://effect.website/play#e9317240a36c
Was this page helpful?