Skip to content

Private network blocklist cache does not reload when private-networks.yaml changes #4091

@1PoPTRoN

Description

@1PoPTRoN

Description

nemoclaw/src/blueprint/private-networks.ts loads nemoclaw-blueprint/private-networks.yaml on first use, builds a node:net BlockList, and memoizes it in the module-level cached value.

The cache is only invalidated through resetCache(), which is exposed for tests. In a long-running plugin process, changes to private-networks.yaml are not picked up until the process restarts.

This is fine for short-lived CLI execution, but the OpenClaw plugin can remain loaded for the lifetime of an agent session. If the private network list changes while the process is running, the existing BlockList remains stale.

Expected behavior

The loader should keep the cache for unchanged files, but refresh it when private-networks.yaml changes. A simple metadata check such as mtimeMs plus file size on each load() call would keep the existing synchronous style while avoiding stale blocklists.

Actual behavior

Once getPrivateNetworks(), getNetworkEntries(), isPrivateIp(), or isPrivateHostname() loads the YAML once, later calls reuse the original cached BlockList even if the YAML file has changed.

Affected file

  • nemoclaw/src/blueprint/private-networks.ts

Reproduction Steps

  1. Load the private network blocklist once through getPrivateNetworks() or isPrivateHostname().
  2. Modify nemoclaw-blueprint/private-networks.yaml or mock the file contents in a unit test.
  3. Call getPrivateNetworks() or isPrivateHostname() again without calling resetCache().
  4. Observe that the previous BlockList is still used.
  5. Restart the process or call resetCache().
  6. Observe that the updated YAML is only picked up after that manual invalidation.

Minimal regression expectation:

const before = getPrivateNetworks();

writeUpdatedPrivateNetworksYaml();

const after = getPrivateNetworks();

expect(after).not.toBe(before);
expect(isPrivateHostname("newly-blocked-address-or-host")).toBe(true);

Environment

  • OS: macOS / Linux / Windows + WSL2
  • Node.js: >=22.16.0
  • Docker: Not required for reproduction
  • NemoClaw: current main
  • Affected runtime: long-running OpenClaw plugin process

Debug Output

Not applicable. This is a cache invalidation issue visible from static inspection and a small unit test.

Relevant behavior:

- `private-networks.ts` stores the parsed YAML and `BlockList` in module-level `cached`.
- `load()` returns `cached` immediately after the first load.
- `resetCache()` is test-only and not part of normal plugin refresh behavior.

Logs

No runtime logs are emitted for this path.

A focused regression test should fail before the fix and pass after adding file metadata-based invalidation:


npm test -- private-networks.test.ts

Checklist

  • I confirmed this bug is reproducible
  • I searched existing issues and this is not a duplicate

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: policyNetwork policy, egress rules, presets, or sandbox policy
    No fields configured for Enhancement.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions