From 9951e9912e6c4c954e5d6ed2b482a4078abd7a61 Mon Sep 17 00:00:00 2001 From: Kerry Huang Date: Tue, 12 May 2026 11:42:18 +0800 Subject: [PATCH] fix(rcc): guard against None stdout/stderr in plugin validate hook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Windows, `subprocess.run(["claude", "plugin", "validate", ...])` can return a CompletedProcess where stdout/stderr are None instead of empty strings (observed when the claude CLI is invoked via npm/cmd shim and exits with no captured output before text-mode decoding completes). The concatenation `result.stdout + result.stderr` then raises `TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'`, which the outer try/except surfaces as a warning to the user: ⚠ validate-frontmatter []: - plugin validate failed: unsupported operand type(s) for +: 'NoneType' and 'str' Coerce both streams to "" before concatenation so the hook stays silent when claude CLI produces no output. No behavior change when both are strings. --- plugins/rcc/hooks/validate_frontmatter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/rcc/hooks/validate_frontmatter.py b/plugins/rcc/hooks/validate_frontmatter.py index 798dabc..2614726 100644 --- a/plugins/rcc/hooks/validate_frontmatter.py +++ b/plugins/rcc/hooks/validate_frontmatter.py @@ -60,7 +60,7 @@ def check_plugin_validate(plugin_dir: Path) -> list[str]: ["claude", "plugin", "validate", str(plugin_dir)], capture_output=True, text=True, timeout=30 ) - output = (result.stdout + result.stderr).strip() + output = ((result.stdout or "") + (result.stderr or "")).strip() if result.returncode != 0 and output: return [f"plugin validate: {line}" for line in output.splitlines() if line.strip()] except FileNotFoundError: