NVIDIA-NeMo / NVIDIA-NeMo/nemo-platform

[Inference Gateway][Switchyard] Deleting one VM unregisters factories still referenced by live VMs (catalog-visible but 500 Factory-not-found)

Open
#1,341 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
78
Forks
23
Avg merge
1d 14h
Merged PRs (30d)
578

Description

Summary

Deleting ANY Switchyard VirtualModel can break inference for OTHER, still-live Switchyard VMs: the surviving VM stays catalog-visible but every inference request answers 500 {"detail": "Factory not found for config hash ..."}.

Tracked internally as NVBug 6563245 (filed 2026-08-05, hit daily by the QA skill-eval suite where VMs are created/destroyed per test).

Root cause

The IGW lifecycle dispatcher (middleware_registry._sdk_vm_to_plugin_vm) builds plugin VirtualModels without mapping the entity id — every on_virtual_model_upserted/on_virtual_model_destroyed hook receives id == "".

nemo_switchyard.middleware keyed its per-VM bookkeeping on that id:

  • on_virtual_model_upserted: VM_CONFIG_MAPPING[virtual_model.id] = hashes -> ALL VMs collapse into the single "" slot; each upsert overwrites the previous VM's entry.
  • on_virtual_model_destroyed: VM_CONFIG_MAPPING.pop(vm_id) pops the shared slot, computes remaining_hashes without the surviving VMs, and unregisters factories they still reference.

Server log capture of the collision (revision 5d4aa2540):

07:48:33.483 Registered factory 'nemo-switchyard-random_routing-0c264eb2f00f7d17' for VM 'default/skill-eval-swy-claude-...'
07:48:33.484 Unregistered factory 'nemo-switchyard-random_routing-0c264eb2f00f7d17'   <- destroy of the PREVIOUS VM, 1ms later
             (surviving VM's next request => 500 Factory not found)

Live reproduction (same revision, unfixed)

create race-a (switchyard random_routing)  -> 201
create race-b (identical config)           -> 201
invoke race-b                              -> 200
delete race-a                              -> 204
invoke race-b                              -> 500 "Factory not found for config hash 6e24859f4d219a91 (VM default/race-ctl-b)"

Fix

Key VM_CONFIG_MAPPING by vm_key (workspace/name) — the identity both hooks reliably carry. Two-line change in plugins/nemo-switchyard/src/nemo_switchyard/middleware.py plus regression tests reproducing the production (id-less) VM shape.

With the fix (source deployment on :8090): the same sequence ends invoke race-b -> 200, correctly routed; plugin suite 77 passed; mutation check confirms the new tests fail on the unfixed code.

Note: the SSE double-encoding on /v1/responses for Switchyard VMs is a SEPARATE defect (NVBug 6563029) and is not addressed here.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in plugins/nemo-switchyard/src/nemo_switchyard/middleware.py and trace the on_virtual_model_upserted and on_virtual_model_destroyed hooks, especially their vm_key and VM_CONFIG_MAPPING usage. Add regression tests using the id-less VM shape described in the issue. Done means deleting one VM no longer unregisters factories still required by a surviving VM, and the surviving VM continues to return a successful inference response.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.