[Bug]: mine.update clear=True raises UnboundLocalError on the master and stores nothing

Aperta Adatta ai principianti
#70,622 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 3 giorni

@cestercian ci sta già lavorando.

Dal 1/11/2026.

  • #70633 di @cestercian — aperta

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
74/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
python
Ambito
backend

Direzione di ricerca

Il bug si trova in RemoteFuncs._mine() in salt/daemons/masterapi.py: data viene assegnato solo nel percorso senza clear, ma la chiamata finale self.cache.store lo usa sempre. Leggi quella funzione e le chiamate di lettura e scrittura della cache, poi riproduci con salt-call mine.update clear=True e controlla salt-run cache.mine. Il lavoro è completo quando clear rimuove le voci obsolete senza UnboundLocalError, clear=False continua a unire i dati, e un test unitario per _mine copre entrambi i percorsi.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

What happened?

RemoteFuncs._mine() only assigns data when clear is false, but always stores data:

https://github.com/saltstack/salt/blob/a98db5df8f42d50f21276b88ccc3136ee70a482a/salt/daemons/masterapi.py#L737-L744

So every _mine request with clear: True (only mine.update clear=True sends one; mine.send and the __mine_interval schedule use the default clear=False) fails on the master with:

[salt.master      :3541][ERROR   ] Error in function _mine:
Traceback (most recent call last):
  File ".../salt/master.py", line 3535, in run_func
    ret = getattr(self, func)(load)
  File ".../salt/master.py", line 3646, in _sync_mine
    return self.masterapi._mine(load, skip_verify=False)
  File ".../salt/daemons/masterapi.py", line 744, in _mine
    self.cache.store(cbank, ckey, data)
UnboundLocalError: cannot access local variable 'data' where it is not associated with a value

(local variable 'data' referenced before assignment on Python 3.10.) Nothing is written, so the old mine entries stay, including ones for functions no longer in mine_functions, and the new data is dropped too. The minion doesn't notice: mine.update returns True once the _minion_mine event is fired, and Minion._mine_send()'s reply from the master is ignored.

This came in with #55760. 5525864060 stored new_data but had a new_ddata typo in the merge branch, and f1e8079486 fixed the typo by changing the store to self.cache.store(cbank, ckey, data), which isn't bound when clearing. Before that (63d8246a5c) the clear path stored load["data"]. Both commits are first in v3000.0rc1, so every release since 3000 has this.

To reproduce, master with default settings (minion_data_cache: True), minion with:

mine_functions:
  test.ping: []
  test.arg:
    - hello
salt-call mine.send stale mine_function=test.echo text=old
salt-call mine.update clear=True
salt-run cache.mine tgt=<minion id>

Expected: only test.arg and test.ping left, since clear is documented as "Specifies whether updating will clear the existing values (True), or whether it will update them (False)". Actual: stale is still there, salt-call returns True and the master logs the traceback above. salt <minion id> mine.update clear=True does the same, and salt <minion id> mine.get <minion id> stale still returns old. salt-run mine.update <minion id> clear=True doesn't hit it, but only because the runner hands clear to LocalClient.cmd() rather than to the function, so the minion runs a plain mine.update (separate bug).

Proposed fix, which is what 5525864060 was going for:

             if not load.get("clear", False):
                 data = self.cache.fetch(cbank, ckey)
                 if isinstance(data, dict):
                     data.update(new_data)
-            self.cache.store(cbank, ckey, data)
+                    new_data = data
+            self.cache.store(cbank, ckey, new_data)
         return True

With that applied to the 3008.x master the steps above leave only test.arg and test.ping and nothing is logged; clear=False still merges. There's no test for RemoteFuncs._mine today. I can send a PR against 3008.x with a unit test.

Type of salt install

other (please specify in bug details)

Major version

3006.x, 3007.x, 3008.x

What supported OS are you seeing the problem on? Can select multiple. (If bug appears on an unsupported OS, please open a GitHub Discussion instead)

rockylinux-10

salt --versions-report output
Not a package install: reproduced with salt-master and salt-minion run from
source exports of 3008.x (a98db5df8f, Python 3.14.8), 3007.x (3ee458139d,
Python 3.12.15) and 3006.x (888f452db2, Python 3.11.16) on Rocky Linux 10.2.
Same result on all three; the traceback ends at masterapi.py line 744, 743
and 729 respectively.

RemoteFuncs._mine is identical on 3008.x and master (b78fd91bfe); 3006.x and
3007.x only differ from it in the cache bank/key names.
Lingua principale
Python
Stelle
15.8k
Fork
5.6k
Merge medio
5g 9h
PR unite (30g)
99

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di saltstack/salt

Tutte le issue di saltstack/salt

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.