desloppify detect phpstan_error (and likely any detector via detect) crashes with OSError: [Errno 36] File name too long once the project accumulates a modest number of zone overrides. The stringified argparse.Namespace (including the full runtime.config dict with all zone_overrides) is being passed where subprocess.Popen expects a path, so ENAMETOOLONG fires as soon as the Namespace repr() exceeds the kernel's filename limit.
Impact for me: after hitting this, scan could no longer refresh phpstan_error findings, and the corresponding state entries became stuck even though phpstan analyse itself exits 0. I had to desloppify suppress phpstan_error::src/ with a truthful attest to unblock.
Environment
- desloppify 0.9.15 (pipx)
- Python 3.12.3
- Linux 6.6.87.2-microsoft-standard-WSL2 (Ubuntu)
- Language: PHP (mid-tier plugin, tool = phpstan, depth 5/8)
Reproduction
- In any project scanned by desloppify, apply ~20+ zone overrides (e.g. one per test file):
for f in tests/Unit/**/*.php; do desloppify zone set "$f" test; done
- Run any detector subcommand:
desloppify detect phpstan_error
With ~21 overrides on my project, this fails 100% of the time.
Expected
The detector re-runs phpstan and refreshes phpstan_error::… findings in state.
Actual
OSError: [Errno 36] File name too long: 'Namespace(lang=None, exclude=None, command=\'detect\',
detector=\'phpstan_error\', top=20, path=\'/home/johns/repos/querri-phpembed\', json=False,
fix=False, category=\'all\', threshold=None, file=None, lang_opt=None,
runtime=CommandRuntime(config={\'target_strict_score\': 85, …, \'zone_overrides\':
{\'tests/Unit/ConfigTest.php\': \'test\', \'tests/Unit/Exceptions/ApiExceptionTest.php\': \'test\',
…21 entries…}, …}))'
Full traceback:
File ".../desloppify/cli.py", line 284, in main
handler(args)
File ".../desloppify/app/commands/detect.py", line 87, in cmd_detect
lang.detect_commands[detector](args)
File ".../desloppify/languages/_framework/generic_parts/tool_factories.py", line 121, in detect
result = run_tool_result(cmd, path, parser, run_subprocess=run_subprocess)
File ".../desloppify/languages/_framework/generic_parts/tool_runner.py", line 74, in run_tool_result
result = runner(
File "/usr/lib/python3.12/subprocess.py", line 548, in run
with Popen(*popenargs, **kwargs) as process:
File "/usr/lib/python3.12/subprocess.py", line 1955, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
OSError: [Errno 36] File name too long: 'Namespace(...)'
Suspected cause
In generic_parts/tool_runner.py:74, run_tool_result's runner(...) call appears to be receiving the full args Namespacewhere subprocess.run expects either a list/string command or an executable=<path> kwarg. The Namespace's __str__() isbeing coerced into a path and tripping ENAMETOOLONG as soon as its length exceeds ~255 bytes — which happens easily oncezone_overrides has ~20 entries.
The underlying detector command (phpstan in this case) is never actually invoked.
Suggested fix direction (guess, not verified)
tool_runner.py should pass only the resolved command list + working directory to subprocess.run, never the argparse Namespace. A defensive check/type-hint on runner's inputs would surface this at call sites rather than deep in _execute_child.
Workaround
desloppify config unset exclude and clearing zone overrides with desloppify zone clear <file> restores detect to a working state, at the cost of losing the classification signal the overrides provided. desloppify suppress<detector>::<prefix> with an attest is a runtime workaround for the stale-findings symptom.
desloppify detect phpstan_error(and likely any detector viadetect) crashes withOSError: [Errno 36] File name too longonce the project accumulates a modest number of zone overrides. The stringifiedargparse.Namespace(including the fullruntime.configdict with allzone_overrides) is being passed wheresubprocess.Popenexpects a path, soENAMETOOLONGfires as soon as the Namespacerepr()exceeds the kernel's filename limit.Impact for me: after hitting this,
scancould no longer refreshphpstan_errorfindings, and the corresponding state entries became stuck even thoughphpstan analyseitself exits 0. I had todesloppify suppress phpstan_error::src/with a truthful attest to unblock.Environment
Reproduction
With ~21 overrides on my project, this fails 100% of the time.
Expected
The detector re-runs phpstan and refreshes
phpstan_error::…findings in state.Actual
Full traceback:
Suspected cause
In
generic_parts/tool_runner.py:74,run_tool_result'srunner(...)call appears to be receiving the fullargsNamespacewheresubprocess.runexpects either a list/string command or anexecutable=<path>kwarg. The Namespace's__str__()isbeing coerced into a path and trippingENAMETOOLONGas soon as its length exceeds ~255 bytes — which happens easily oncezone_overrideshas ~20 entries.The underlying detector command (phpstan in this case) is never actually invoked.
Suggested fix direction (guess, not verified)
tool_runner.pyshould pass only the resolved command list + working directory tosubprocess.run, never the argparse Namespace. A defensive check/type-hint onrunner's inputs would surface this at call sites rather than deep in_execute_child.Workaround
desloppify config unset excludeand clearing zone overrides withdesloppify zone clear <file>restoresdetectto a working state, at the cost of losing the classification signal the overrides provided.desloppify suppress<detector>::<prefix>with an attest is a runtime workaround for the stale-findings symptom.