ruvnet/ruflo · error · Error

WgMeshService.buildInterfaceConfig: local identity not set;

Error message

WgMeshService.buildInterfaceConfig: local identity not set; call setLocalIdentity() first

What it means

buildInterfaceConfig refuses to render a wg-quick config because the local node's WireGuard keypair or mesh IP has not been established via setLocalIdentity(). The [Interface] section requires a PrivateKey and Address; without them the generated config would be unusable, so the operation is a precondition failure rather than a bad-peer problem.

Source

Thrown at v3/@claude-flow/plugin-agent-federation/src/domain/services/wg-mesh-service.ts:193

  }

  getMeshSubnet(): string {
    return this.meshSubnet;
  }

  /**
   * Build a `wg-quick`-compatible config string from current peers.
   *
   * Peers below WG_MIN_MESH_TRUST (UNTRUSTED) are excluded entirely.
   * Suspended peers stay in the config but with `AllowedIPs =` empty
   * (soft-block). Evicted peers are dropped completely.
   *
   * Operator writes this to `/etc/wireguard/<interface>.conf` and runs
   * `wg-quick up <interface>`.
   */
  buildInterfaceConfig(peers: readonly FederationNode[]): string {
    if (!this.localKey || !this.localMeshIP) {
      throw new Error('WgMeshService.buildInterfaceConfig: local identity not set; call setLocalIdentity() first');
    }
    const lines: string[] = [];
    lines.push('# Generated by ruflo federation plugin — ADR-111 Phase 2.');
    lines.push('# Operator MUST review before `wg-quick up`. Trust-graded port');
    lines.push('# rules (WG_NETWORK_GATES) are not enforced here — Phase 4 will');
    lines.push('# project them into nftables/pf. v1 uses mesh-IP isolation only.');
    lines.push('[Interface]');
    lines.push(`PrivateKey = ${this.localKey.privateKey}`);
    lines.push(`Address = ${this.localMeshIP}`);
    lines.push(`ListenPort = ${this.listenPort}`);
    lines.push('');
    for (const peer of peers) {
      if (peer.trustLevel < WG_MIN_MESH_TRUST) continue;
      // Security: validate every spliced field. A compromised but-signed
      // peer can otherwise inject extra [Peer] blocks via newline-laden
      // wgEndpoint. readSafePeerWgFields enforces base64/CIDR/host:port
      // regexes; mismatches skip the peer entirely (safer than partial-write).
      const safe = readSafePeerWgFields(peer);

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Call setLocalIdentity() with the node's keypair/identity before building interface configs.
  2. Order startup so identity initialization precedes mesh configuration.
Defensive patterns

Strategy: validation

When it happens

Trigger: buildInterfaceConfig is called on WgMeshService before setLocalIdentity() has been called.

Common situations: Mesh configuration built during startup before identity bootstrap completes.


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/744042d2b663ebcd. Report an issue: GitHub.