Skip to content

Background services ran their work on the mesh router — issue it off-router - #1167

Merged
rbuergi merged 5 commits into
mainfrom
fix/1113-router-as-work-participant
Aug 10, 2026
Merged

rbuergi merged 5 commits into
mainfrom
fix/1113-router-as-work-participant

Conversation

@rbuergi

@rbuergi rbuergi commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #1113

No traffic was ever dropped. ReportRouterTraffic is a detector, not a guard — it logs and returns before routing, so every flagged delivery routed exactly as it would have without it. The issue body's "potential functional impact" does not exist; the cost was log volume and router action-block contention.

What was producing the 840 ROUTER_TRAFFIC errors

Live-log triage (24 h of the current memex image, aggregated by type+role) — corroborated by the read-only A/B across the three AKS portals (see the review comment below) — put the volume here:

Arm Share Producer Status
RawJson sender=mesh (+ CreateNodeRequest/CreateOrUpdateNodeRequest target=mesh) ~97% node-CRUD fallback ran requests AND responses through the router — one report per receiving hub, so the count scales with node count already fixed on main by the nodeops retarget (eea2dd2)
ValidateTokenRequest/Response (issue sample) SignalR/gRPC transport issued token validation on the router already fixed (50bfb0f, in the deployed image)
GetDataResponse/DeliveryFailure/ImportContentResponse/CreateNodeResponse target=mesh tail this PR, producer 1 fixed here
RawJson sender=mesh at the issuing hub (bounce of a missing-node read) subset of the RawJson volume this PR, producer 2 fixed here
ClickedEvent / UnsubscribeRequest / PatchDataChangeRequest (issue sample only) artifacts of the pre-953ab9245 detector, which keyed on the receiving hub's Address and reported every routing hop not live defects — images carrying 953ab9245 emit none

Producer 1 — mesh-singleton services issue work on the DI root hub (= the router)

InstanceAutoRegistrationService (default-install seed + ledger), ModuleDiscoveryService, PackageInstaller, RegistryTokenResolver, LogIncidentIngestService, GitSync services, InstanceSyncWorker and MeshDocumentSink all hold the DI-injected IMessageHub — the root mesh hub — and issued request/response work on it:

  • one-shot GetMeshNode reads → GetDataResponse / DeliveryFailure addressed straight back at mesh/{id} (production lines: sender: Hosting/_Access/Public_Access, sender: Plugins/_DefaultInstallLedger),
  • content imports → ImportContentResponse → mesh (sender: Agent),
  • target-less CreateOrUpdateNodeRequests — which execute on the posting hub, so the plugin default-install's bulk upserts and log-incident creates ran on the router's single-threaded action block (the starvation shape the detector exists for).

Fix: MeshExtensions.NodeOperationIssuingHub — the off-router issuing seam extracted from MeshService.IssuingHub — applied at the helper roots (GetMeshNode, the ImportContent/SyncContentFiles builders) so every mesh-singleton caller of those helpers is covered, plus every direct target-less CreateOrUpdate post. A non-router hub gets itself back, so portal/session/import callers are byte-for-byte unchanged.

Known survivors (direct cross-hub Observe on the root hub that bypasses the helpers — named in the review comment): PackageInstaller.cs PingRequest probe loop and ContentIndexingObserver.cs's cross-hub GetDataRequest. A separate follow-up PR against main covers those (deliberately not stacked and without a closing keyword).

Producer 2 — the guard misclassified the router's own undeliverable-mail NACK

RoutingServiceBase.PostNotFound / NackRouteFailure post their DeliveryFailure from the mesh hub via ResponseFor — explicitly "routing infrastructure's OWN NotFound NACK", i.e. the router doing its job, but the detector reported it as work (RawJson has the mesh hub as sender on every bounced read of a missing node; the payload is RawJson-packed at the detector — RawJson means "opaque here", not a real message type — so the request-id correlation is the structural signal). Fix: RouterTrafficRule excludes a response the router posts at another hub. Coverage is preserved: a response addressed at the router still reports (it proves the router issued a request), as does any non-response send from it. NodeOperationIssuingHubTest caught this arm red before the classification fix — the missing-node read's bounce produced exactly the production line. Per Copilot review, the pre-existing 3-arg RoleOf overload is kept for binary compatibility (shipped Contract package).

Evidence

  • NodeOperationIssuingHubTest (new, MonolithMeshTestBase): seam shape, read seam, missing-node bounce, write seam, and the detector's own captured ERROR stream must stay empty. Red before producer-2's fix (caught the bounce), green after.
  • RouterTrafficRuleTest extended with the NACK cases (exclusion + its three non-widening counter-cases); RouterTrafficDetectorTest 16/16.
  • Suites over every touched module: NodeOperations 89/89, PluginCatalog 234/236 (the 2 = StaleStampRootBindingTest, the pre-existing main flake fixed by The installer started a teardown and handed back without waiting for it #1153 — 3/3 green after merging main), Observability 105/105, GitSync 157/157, ContentCollections 29/29, InstanceSync 24/24, Indexing.Graph 31/31, What's New integrity 1/1.
  • Touched projects build clean with -c Release -warnaserror.

🤖 Generated with Claude Code

https://claude.ai/code/session_01UYLgoPK1qLtyxZ2ixdFtj5

rbuergi and others added 2 commits August 10, 2026 18:15
…router

Issue #1113: 840 ROUTER_TRAFFIC errors in ~8h across 6 memex pods — deliveries with the
mesh ROUTER hub as sender or target. Live-log triage (24h, current image) put ~97% of
the volume on the node-CRUD fallback already fixed by the nodeops retarget (eea2dd2)
and the transport token validation fixed by 50bfb0f. Two producer classes remained on
main; both are fixed here at their roots.

1. Mesh-singleton services hold the DI-injected root hub — the ROUTER — and issued
   request/response work on it: one-shot GetMeshNode reads (GetDataResponse /
   DeliveryFailure addressed straight back at mesh/{id}: "sender:
   Hosting/_Access/Public_Access", "sender: Plugins/_DefaultInstallLedger"), content
   imports (ImportContentResponse → mesh, "sender: Agent"), and target-less
   CreateOrUpdateNodeRequests — which EXECUTE on the posting hub, so the plugin
   default-install's bulk upserts ran on the router's action block.

   Fix: NodeOperationIssuingHub — the shared off-router issuing seam, extracted from
   MeshService.IssuingHub — applied at the helper roots (GetMeshNode, the content
   import/sync builders) and at every direct target-less CreateOrUpdate post
   (LogIncidentIngestService, PackageInstaller, ModuleDiscoveryService,
   InstanceSyncWorker, GitSync services, MeshDocumentSink). A non-router hub gets
   itself back, so portal/session/import callers are byte-for-byte unchanged.

2. The routing layer's own undeliverable-mail NACK (RoutingServiceBase.PostNotFound /
   NackRouteFailure) posts its DeliveryFailure from the mesh hub via ResponseFor — the
   router's own duty, reported as a violation ("RawJson has the mesh hub as sender" for
   every bounced read of a missing node; the payload is RawJson-packed at the detector,
   so the request-id correlation is the structural signal). Fix: RouterTrafficRule
   excludes a response the router posts at another hub; a response ADDRESSED AT the
   router still reports (it proves the router issued a request), as does any
   non-response send from it.

Pinned by NodeOperationIssuingHubTest (the read seam, the missing-node bounce, the
write seam, and the detector's own capture staying silent — the bounce line was caught
by this very test before fix 2) and the extended RouterTrafficRuleTest NACK cases.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UYLgoPK1qLtyxZ2ixdFtj5
Copilot AI lite review requested due to automatic review settings August 10, 2026 16:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses issue #1113 by ensuring background/mesh-singleton services and helper paths no longer issue request/response work on the root mesh hub (the router). It introduces a shared “issuing hub” seam to route node operations off-router, and refines the router-traffic detector to avoid flagging the router’s own undeliverable-message NACK responses.

Changes:

  • Introduce and apply NodeOperationIssuingHub() so reads/imports/upserts issued from the DI root mesh hub run on the dedicated off-router execution hub.
  • Refine ROUTER_TRAFFIC detection to exclude router-originated responses (NACKs) while still reporting real router-as-end violations.
  • Add/extend tests to pin both the off-router issuing behavior and the tightened router-traffic rule behavior.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
test/MeshWeaver.Messaging.Hub.Test/RouterTrafficRuleTest.cs Extends rule coverage for router NACK response exclusion and non-widening cases.
test/MeshWeaver.Hosting.Monolith.Test/NodeOperationIssuingHubTest.cs New integration test pinning off-router issuing behavior and asserting detector silence.
src/MeshWeaver.PluginCatalog/PackageInstaller.cs Routes target-less upserts through NodeOperationIssuingHub() to keep work off the router.
src/MeshWeaver.PluginCatalog/ModuleDiscoveryService.cs Uses NodeOperationIssuingHub() for hosted-service writes that previously executed on the router.
src/MeshWeaver.Observability/LogIncidentIngestService.cs Issues log-incident node upserts off-router to avoid self-triggering router-traffic errors.
src/MeshWeaver.Messaging.Hub/MessageHub.cs Passes response-correlation signal into RouterTrafficRule for correct NACK classification.
src/MeshWeaver.Messaging.Contract/RouterTrafficRule.cs Adds response-aware exclusion logic for router-posted NACK responses.
src/MeshWeaver.Mesh.Contract/MeshNodeStreamExtensions.cs Issues GetMeshNode reads via NodeOperationIssuingHub() and aligns diagnostics with the issuing hub.
src/MeshWeaver.Mesh.Contract/MeshExtensions.cs Introduces NodeOperationIssuingHub() extension method as the shared off-router seam.
src/MeshWeaver.InstanceSync/InstanceSyncWorker.cs Routes target-less sync upserts through NodeOperationIssuingHub().
src/MeshWeaver.Hosting/MeshService.cs Reuses the shared NodeOperationIssuingHub() seam for CRUD issuing behavior.
src/MeshWeaver.GitSync/IssueService.cs Issues GitHub issue node upserts off-router.
src/MeshWeaver.GitSync/GitHubWebhookProcessor.cs Routes webhook-driven upserts off-router.
src/MeshWeaver.GitSync/GitHubSyncService.cs Uses NodeOperationIssuingHub() for config writes to avoid router involvement.
src/MeshWeaver.GitSync/GitHubCredentialService.cs Issues credential writes off-router.
src/MeshWeaver.Documentation/Data/WhatsNew/2026-08-10-router-stays-a-router.md Adds a “What’s New” entry documenting the operational fix.
src/MeshWeaver.ContentCollections/ContentImportExtensions.cs Ensures import request/response is issued off-router for mesh-singleton callers.
src/MeshWeaver.ContentCollections.Indexing.Graph/MeshDocumentSink.cs Routes indexing sink upserts off-router.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@github-actions

github-actions Bot commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 0)

705 tests  ±0   705 ✅ ±0   14m 11s ⏱️ +32s
 10 suites ±0     0 💤 ±0 
 10 files   ±0     0 ❌ ±0 

Results for commit 35211f0. ± Comparison against base commit b4920dc.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 3)

   11 files  ±0     11 suites  ±0   9m 49s ⏱️ +44s
1 984 tests ±0  1 876 ✅ ±0  108 💤 ±0  0 ❌ ±0 
2 168 runs  +1  2 060 ✅ +1  108 💤 ±0  0 ❌ ±0 

Results for commit 35211f0. ± Comparison against base commit b4920dc.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 5)

1 786 tests  ±0   1 594 ✅ ±0   7m 49s ⏱️ -36s
   11 suites ±0     192 💤 ±0 
   11 files   ±0       0 ❌ ±0 

Results for commit 35211f0. ± Comparison against base commit b4920dc.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 1)

1 252 tests  +58   1 252 ✅ +58   6m 49s ⏱️ +25s
   11 suites ± 0       0 💤 ± 0 
   11 files   ± 0       0 ❌ ± 0 

Results for commit 35211f0. ± Comparison against base commit b4920dc.

This pull request removes 76 and adds 134 tests. Note that renamed tests count towards both.
MeshWeaver.Hosting.Monolith.Test.NodeOperationOriginTest ‑ NodeCreate_IsExecutedByTheDedicatedHub_NeverByTheRouter
MeshWeaver.Hosting.Monolith.Test.NodeTypeAssemblyLeakTest ‑ NodeTypeAssemblyContext_IsCollected_AfterMeshDisposal
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeLeaseTest ‑ DifferentFrameworkVersions_DoNotContend
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeLeaseTest ‑ DisposingTwice_IsHarmless
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeLeaseTest ‑ FreshLease_IsNotStolen
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeLeaseTest ‑ HeartbeatInterval_IsWellInsideTheStaleWindow
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeLeaseTest ‑ ReleasingTheLease_LetsTheNextPodTakeIt
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeLeaseTest ‑ SecondPod_DoesNotGetTheLease
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeLeaseTest ‑ StaleLease_IsStolen
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeLeaseTest ‑ UnusableDirectory_StillAllowsBaking
…
MeshWeaver.Hosting.Monolith.Test.NodeOperationIssuingHubTest ‑ WorkIssuedWhileHoldingTheRouter_NeverMakesTheRouterAnEnd
MeshWeaver.Hosting.Monolith.Test.NodeOperationTargetTest ‑ ChildOfAnExecutionHub_WalksUpToThatHub_NotPastItToTheRouter
MeshWeaver.Hosting.Monolith.Test.NodeOperationTargetTest ‑ HubWithHandlersButNoExecutionOptIn_StillFallsBackToTheSharedExecutionHub
MeshWeaver.Hosting.Monolith.Test.NodeOperationTargetTest ‑ HubWithoutTheOptIn_FallsBackToTheDedicatedExecutionHub_NeverTheRouter
MeshWeaver.Hosting.Monolith.Test.NodeOperationTargetTest ‑ PortalHubThatDeclaredExecution_TargetsItself_NotTheRouter
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeGateStateTest ‑ AddNodeTypeBakeGate_DefaultRegistration_IsNotArmed
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeGateStateTest ‑ AddNodeTypeBakeGate_WhenHostGates_IsArmed
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeGateStateTest ‑ AlreadyBrokenTypeThatFailsAgain_DoesNotGate
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeGateStateTest ‑ Arming_DoesNotChangeWhichOutcomesGate
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeGateStateTest ‑ CleanRun_CompletesHealthy
…

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 2)

1 968 tests   - 53   1 966 ✅  - 53   6m 23s ⏱️ -30s
   11 suites ± 0       2 💤 ± 0 
   11 files   ± 0       0 ❌ ± 0 

Results for commit 35211f0. ± Comparison against base commit b4920dc.

This pull request removes 129 and adds 76 tests. Note that renamed tests count towards both.
MeshWeaver.Hosting.Monolith.Test.NodeOperationTargetTest ‑ ChildOfAnExecutionHub_WalksUpToThatHub_NotPastItToTheRouter
MeshWeaver.Hosting.Monolith.Test.NodeOperationTargetTest ‑ HubWithHandlersButNoExecutionOptIn_StillFallsBackToTheSharedExecutionHub
MeshWeaver.Hosting.Monolith.Test.NodeOperationTargetTest ‑ HubWithoutTheOptIn_FallsBackToTheDedicatedExecutionHub_NeverTheRouter
MeshWeaver.Hosting.Monolith.Test.NodeOperationTargetTest ‑ PortalHubThatDeclaredExecution_TargetsItself_NotTheRouter
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeGateStateTest ‑ AddNodeTypeBakeGate_DefaultRegistration_IsNotArmed
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeGateStateTest ‑ AddNodeTypeBakeGate_WhenHostGates_IsArmed
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeGateStateTest ‑ AlreadyBrokenTypeThatFailsAgain_DoesNotGate
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeGateStateTest ‑ Arming_DoesNotChangeWhichOutcomesGate
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeGateStateTest ‑ CleanRun_CompletesHealthy
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeGateStateTest ‑ CompileErrorStillGates_EvenAlongsideATimeout
…
MeshWeaver.Hosting.Monolith.Test.NodeOperationOriginTest ‑ NodeCreate_IsExecutedByTheDedicatedHub_NeverByTheRouter
MeshWeaver.Hosting.Monolith.Test.NodeTypeAssemblyLeakTest ‑ NodeTypeAssemblyContext_IsCollected_AfterMeshDisposal
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeLeaseTest ‑ DifferentFrameworkVersions_DoNotContend
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeLeaseTest ‑ DisposingTwice_IsHarmless
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeLeaseTest ‑ FreshLease_IsNotStolen
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeLeaseTest ‑ HeartbeatInterval_IsWellInsideTheStaleWindow
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeLeaseTest ‑ ReleasingTheLease_LetsTheNextPodTakeIt
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeLeaseTest ‑ SecondPod_DoesNotGetTheLease
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeLeaseTest ‑ StaleLease_IsStolen
MeshWeaver.Hosting.Monolith.Test.NodeTypeBakeLeaseTest ‑ UnusableDirectory_StillAllowsBaking
…

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 4)

1 351 tests  ±0   1 346 ✅ ±0   9m 55s ⏱️ +26s
   11 suites ±0       5 💤 ±0 
   11 files   ±0       0 ❌ ±0 

Results for commit 35211f0. ± Comparison against base commit b4920dc.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

Test Results

   65 files  ±0     65 suites  ±0   54m 59s ⏱️ + 1m 1s
9 046 tests +5  8 739 ✅ +5  307 💤 ±0  0 ❌ ±0 
9 230 runs  +6  8 923 ✅ +6  307 💤 ±0  0 ❌ ±0 

Results for commit 35211f0. ± Comparison against base commit b4920dc.

♻️ This comment has been updated with latest results.

rbuergi and others added 3 commits August 10, 2026 22:38
…t surface

Copilot review: adding the optional isResponse parameter was a binary breaking
change for assemblies compiled against the 3-arg signature. Reintroduce the
original overload delegating to the explicit 4-arg form (default removed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UYLgoPK1qLtyxZ2ixdFtj5
@rbuergi
rbuergi merged commit 6a5d380 into main Aug 10, 2026
18 checks passed
@rbuergi
rbuergi deleted the fix/1113-router-as-work-participant branch August 19, 2026 10:32
@rbuergi

rbuergi commented Oct 11, 2026

Copy link
Copy Markdown
Contributor Author

(re-posted 2026-10-11; originally by @rbuergi on 2026-08-10)

Independent root-cause of #1113 from a parallel investigation converged on the same mechanism as this PR — the seam here is the right one. Three things from that investigation that may be useful, one of which is a gap.

1. The guard is a detector, not a guard — the issue body's impact claim is false. MessageHub.ReportRouterTraffic (MessageHub.cs:1277-1300) runs inside DeliverMessage before routing and never touches the delivery: it logs and returns. So the issue's "potential functional impact … depending on whether the message eventually reached the correct handler" does not happen — every flagged delivery routes exactly as it would without the detector. The cost is log volume and router action-block contention, not lost messages. Worth stating in the PR body so the next reader doesn't go looking for dropped traffic.

2. What "801 occurrences" actually measured. The dedupe key is role:messageType per hub instance, and DeliverMessage fires at every hub a delivery transits — so 801 ≈ one line per receiving hub, not 801 distinct message types. It scales with node count, which is why the number looked catastrophic. Relatedly, the type is almost always RawJson because the mesh hub's route handler calls delivery.Package(...) (MeshBuilder.cs:225-231) before handing to IRoutingService — RawJson means "opaque here", not a real message type.

Also worth knowing: the ClickedEvent / UnsubscribeRequest / PatchDataChangeRequest arms in the issue body are artifacts of the pre-953ab9245 detector, which keyed on the receiving hub's Address and so reported every routing hop. Images carrying 953ab9245 emit zero of those three — they are not live defects.

3. Measured effect of what has already merged (read-only across the three AKS portals — a natural A/B, since they run different images):

Portal Image has eea2dd248 ROUTER_TRAFFIC
memex ci.2732 (fc070f5) no 228 lines / 4.5 h
client-i ci.2749 (412fc5c) yes 29 / 4 h
memex-cloud ci.2760 (0268860) yes 1 line / 2.8 h

~97% already gone. The issue's window (01:08–08:59Z) predates all of it.

4. 🔎 Two producers this PR does not cover. The seam fixes the helper roots, but a direct cross-hub Observe on a root-container singleton still bypasses it — and in the mesh's root container that IMessageHub is the router:

  • src/MeshWeaver.PluginCatalog/PackageInstaller.cs:897 — hub.Observe<PingResponse>(new PingRequest(), o => o.WithTarget(address)) inside Observable.Defer(Probe).Repeat(). A retry loop of router-originated pings on the boot default-install path. This PR edits lines 1144 and 2123 of the same file but not 897.
  • src/MeshWeaver.ContentCollections.Indexing.Graph/ContentIndexingObserver.cs:84 — cross-hub GetDataRequest(ContentCollectionReference), registered via MeshBuilder.ConfigureServices → sp.GetRequiredService<IMessageHub>() in the root container. This PR fixed MeshDocumentSink in the same project but not this one.

Both match the GetDataResponse target=mesh shape observed live. Neither is high-volume, but both survive this PR. A small follow-up is being opened for them against main (not stacked), deliberately without a Fixes #1113 keyword so it doesn't race this PR for the issue.

I also checked the isResponse exclusion for over-suppression and it holds — work sent to the router is still caught at request time via the target role.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Message senders and targets are addressing the mesh router hub directly instead of using the correct portal/import hubs

2 participants