You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
gittensor/utils/config.py:39 — inside check_config(...), which runs on every miner/validator boot via BaseNeuron.__init__ → self.check_config(self.config) — there is a bare print() that writes the resolved neuron path directly to stdout:
defcheck_config(cls, config: Any):
r"""Checks/validates the config namespace object."""bt.logging.check_config(config)
full_path=os.path.expanduser(
'{}/{}/{}/netuid{}/{}'.format(
config.logging.logging_dir,
config.wallet.name,
config.wallet.hotkey,
config.netuid,
config.neuron.name,
)
)
print('full path:', full_path) # ← bare print to stdoutconfig.neuron.full_path=os.path.expanduser(full_path)
ifnotos.path.exists(config.neuron.full_path):
os.makedirs(config.neuron.full_path, exist_ok=True)
This is the onlyprint() call in gittensor/, neurons/, or tests/ outside CLI/JSON-output paths — verified via grep -rn '^\s*print(' --include='*.py' gittensor/ neurons/. The leading 'full path:' formatting strongly suggests it's leftover from initial development/debugging in the upstream Bittensor template (the file still carries the Yuma Rao / OpenTensor 2023 copyright header) and was never removed.
Why this is a problem
Bypasses bt.logging configuration. Every other startup line goes through bt.logging.{info,debug,warning} — operators control verbosity, format, and destination via --logging.* flags or env. This print() ignores all of that. Setting --logging.debug=False does not silence it; redirecting log output via bittensor's mechanism does not capture it.
Pollutes stdout where it isn't expected. Operators running validators/miners under systemd, docker logs, journalctl, structured-log shippers (Vector, Fluent Bit), or any aggregator that distinguishes stdout from logger output get a stray, unstructured line in the wrong stream — different from the rest of the startup trace, harder to filter.
Distinct from Bug: noise in stdout interfere json parsing #956. That issue is about --json CLI commands writing warnings to stdout and breaking jq. This one is in BaseNeuron's startup path, fires on every miner/validator boot regardless of CLI invocation, and isn't reachable through the CLI --json paths Bug: noise in stdout interfere json parsing #956 covers. They're independent fixes.
Steps to Reproduce
Start any neuron (validator, miner, or any subclass of BaseNeuron):
$ python neurons/validator.py --wallet.name foo --wallet.hotkey bar --netuid 74 2>/dev/null
full path: /home/user/.bittensor/miners/foo/bar/netuid74/validator
...
The 2>/dev/null redirect drops bt.logging output (it goes to stderr by default), but the 'full path: ...' line still appears — proving it's on stdout, not the logger stream.
Conversely, python neurons/validator.py ... 1>/dev/null suppresses 'full path:' while leaving the bt.logging trace intact — confirming the same.
Expected Behavior
Either:
Route through the existing logger: bt.logging.debug(f'Neuron full_path: {full_path}') — keeps the diagnostic for anyone who wants it (--logging.debug), respects the operator's logging configuration, and goes to the same stream as the rest of startup output.
Or just drop the line — full_path is already used in the immediately following os.makedirs(...) call, and the value is recoverable from config.neuron.full_path post-init for any operator who wants to inspect it.
(The bt.logging.debug form is already imported in the file at line 23.)
If you'd rather just remove it, that's also a one-line change and avoids the (tiny) extra debug noise.
Scope
Affects only the one print() call. No behaviour change for the path construction itself — config.neuron.full_path and the os.makedirs(...) call on the next two lines are untouched.
Environment
Affected file: gittensor/utils/config.py:39
Branch: test
Reproducible on every neuron boot since the file was inherited from the upstream Bittensor template (commit a85691c "thus spoke zarathustra", per git log -L 39,39:gittensor/utils/config.py).
Description
gittensor/utils/config.py:39— insidecheck_config(...), which runs on every miner/validator boot viaBaseNeuron.__init__ → self.check_config(self.config)— there is a bareprint()that writes the resolved neuron path directly to stdout:This is the only
print()call ingittensor/,neurons/, ortests/outside CLI/JSON-output paths — verified viagrep -rn '^\s*print(' --include='*.py' gittensor/ neurons/. The leading'full path:'formatting strongly suggests it's leftover from initial development/debugging in the upstream Bittensor template (the file still carries the Yuma Rao / OpenTensor 2023 copyright header) and was never removed.Why this is a problem
Bypasses
bt.loggingconfiguration. Every other startup line goes throughbt.logging.{info,debug,warning}— operators control verbosity, format, and destination via--logging.*flags or env. Thisprint()ignores all of that. Setting--logging.debug=Falsedoes not silence it; redirecting log output via bittensor's mechanism does not capture it.Pollutes stdout where it isn't expected. Operators running validators/miners under
systemd,docker logs,journalctl, structured-log shippers (Vector, Fluent Bit), or any aggregator that distinguishes stdout from logger output get a stray, unstructured line in the wrong stream — different from the rest of the startup trace, harder to filter.Distinct from Bug: noise in stdout interfere json parsing #956. That issue is about
--jsonCLI commands writing warnings to stdout and breakingjq. This one is inBaseNeuron's startup path, fires on every miner/validator boot regardless of CLI invocation, and isn't reachable through the CLI--jsonpaths Bug: noise in stdout interfere json parsing #956 covers. They're independent fixes.Steps to Reproduce
BaseNeuron):2>/dev/nullredirect dropsbt.loggingoutput (it goes to stderr by default), but the'full path: ...'line still appears — proving it's on stdout, not the logger stream.python neurons/validator.py ... 1>/dev/nullsuppresses'full path:'while leaving thebt.loggingtrace intact — confirming the same.Expected Behavior
Either:
bt.logging.debug(f'Neuron full_path: {full_path}')— keeps the diagnostic for anyone who wants it (--logging.debug), respects the operator's logging configuration, and goes to the same stream as the rest of startup output.full_pathis already used in the immediately followingos.makedirs(...)call, and the value is recoverable fromconfig.neuron.full_pathpost-init for any operator who wants to inspect it.Suggested Fix
Single-line change:
(The
bt.logging.debugform is already imported in the file at line 23.)If you'd rather just remove it, that's also a one-line change and avoids the (tiny) extra debug noise.
Scope
Affects only the one
print()call. No behaviour change for the path construction itself —config.neuron.full_pathand theos.makedirs(...)call on the next two lines are untouched.Environment
gittensor/utils/config.py:39testa85691c "thus spoke zarathustra", pergit log -L 39,39:gittensor/utils/config.py).