#28235·directus

Array-backed dynamic variable paths drop falsy values

Author: jashkarangiyaCreated Sep 14, 2026Updated Sep 14, 2026
LabelsBugMed ImpactLow Reach

Describe the Bug

Dotted dynamic variable paths backed by arrays drop valid falsy values while resolving the path. Values such as 0, false, and an empty string are removed, even though the property exists.

The shared get helper currently filters nested array results by truthiness. parseDynamicVariable uses that helper for dotted $CURRENT_USER, $CURRENT_ROLES, $CURRENT_ROLE, and $CURRENT_POLICIES paths, so permission filters, validation rules, and presets can receive a shorter list than the one represented by the configured data.

Only null, undefined, and missing properties should be excluded. Keeping null out is intentional because a null operand in a SQL NOT IN list can make the comparison unknown for every row.

This was reviewed with the Directus maintainers and confirmed as a normal correctness issue: https://github.com/directus/directus/security/advisories/GHSA-xgww-wpqg-cx4p#event-1035897

To Reproduce

  1. Resolve a dotted array-backed variable with data equivalent to:

    typescript
    {
      $CURRENT_ROLES: [
        { value: 'blocked' },
        { value: 0 },
        { value: false },
        { value: '' },
        { value: null },
        { value: undefined },
        {},
      ],
    }
  2. Use $CURRENT_ROLES.value as the operand of an _in or _nin filter.

  3. Observe that the resolved list contains only ['blocked'].

  4. The expected list is ['blocked', 0, false, '']. Null, undefined, and the missing property should remain excluded.

The same behavior can be reproduced directly with get(context, '$CURRENT_ROLES.value', null) from @directus/utils.

Directus Version

v12.3.1 and main at 99ebe62

Hosting Strategy

Self-Hosted (Custom)

Database

Database-independent. The values are lost during shared filter parsing before SQL generation.