Skip to content

Bug: "active: true" on a configs[] instance is ignored unless root has active: false #390

@thedavil

Description

@thedavil

Bug: active: true on a configs[] instance is ignored unless root has active: false

Summary

When using a multi-instance dw.json with a configs array, marking an instance as "active": true has no effect unless the root object also has "active": false. This makes the active flag on child instances functionally useless in the most common case — a global dw.json with multiple named sandboxes.

Expected Behavior

A user with the following dw.json should have sandbox1 selected automatically:

{
  "configs": [
    {
      "name": "sandbox1",
      "active": true,
      "hostname": "zzem-060.dx.commercecloud.salesforce.com",
      "clientId": "...",
      "clientSecret": "..."
    },
    {
      "name": "sandbox2",
      "hostname": "zzem-061.dx.commercecloud.salesforce.com",
      "clientId": "...",
      "clientSecret": "..."
    }
  ]
}

Actual Behavior

All config fields resolve as empty (-). The CLI selects the root config object (which has no fields), completely ignoring the instance with "active": true.

Trace output:

[DwJsonSource] Selected config "root" (default to root)
[DwJsonSource] Loaded config
  location: "/Users/my.username/dw.json"
  fields: []

Root Cause

selectConfig() in packages/b2c-tooling-sdk/src/config/dw-json.ts (line 230) gates the active-instance search behind a check that the root itself is explicitly active: false:

// Find active config
if (json.active === false) {                                    // ← BUG: overly narrow guard
  const activeConfig = json.configs.find((c) => c.active === true);
  if (activeConfig) {
    return activeConfig;
  }
}

// Default to root config  ← always reached when root has no active field
return json;

When the root has no active field (the default for any naturally-authored multi-instance file), json.active === false is false, the configs[] array is never searched for an active instance, and selection falls through to the root — which carries no config fields.

The JSDoc comment above selectConfig() (lines 191–194) explicitly documents the intended priority:

 * Selection priority:
 * 1. Named instance (if `instance` option provided)
 * 2. Config marked as `active: true`    ← documented but not working
 * 3. Root-level config

The implementation does not match the documented contract.

Fix

Remove the json.active === false guard. The active-instance search should always run when a configs array exists:

// Find active config
const activeConfig = json.configs.find((c) => c.active === true);
if (activeConfig) {
  logger.trace(
    {selection: 'active', instanceName: activeConfig.name},
    `[DwJsonSource] Selected config "${activeConfig.name}" by active flag`,
  );
  return activeConfig;
}

// Default to root config

The json.active === false guard appears to have been added to prevent the root from being bypassed when it is itself the intended active config, but this is already handled by priority step 3 (fall-through to root). The guard is both redundant for that case and actively harmful for the documented use case.

Workaround

Until fixed, we could add "active": false to the root object:

{
  "active": false,
  "configs": [
    {
      "name": "sandbox1",
      "active": true,
      ...
    }
  ]
}

This is non-obvious, undocumented, and conflicts with the natural mental model of the format.

Impact

  • Users with a global SFCC_CONFIG pointing to a multi-instance dw.json (a recommended pattern for working across sandboxes) get silently empty config with no error or warning.
  • The active flag on child instances is documented and surfaced in tooling (e.g. b2c setup inspect) but has no effect in the common case.
  • The b2c setup inspect output shows all fields as - with no explanation, making the failure hard to diagnose without checking the full trace logs.

Files

  • packages/b2c-tooling-sdk/src/config/dw-json.tsselectConfig(), line 230
  • packages/b2c-tooling-sdk/test/config/ — tests should be added to cover multi-instance active selection without root active: false

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions