Skip to content

skill-creator: fix Windows subprocess + encoding bugs - #1050

Open
gstreet-ops wants to merge 1 commit into
anthropics:mainfrom
gstreet-ops:fix/windows-compat-skill-creator
Open

skill-creator: fix Windows subprocess + encoding bugs#1050
gstreet-ops wants to merge 1 commit into
anthropics:mainfrom
gstreet-ops:fix/windows-compat-skill-creator

Conversation

@gstreet-ops

Copy link
Copy Markdown

Two Windows compatibility fixes for skill-creator scripts

Found while running run_loop.py on Windows 11. Both fixes are 1-line changes.

1. subprocess.Popen(["claude", ...]) fails with [WinError 2]
On Windows the CLI ships as claude.cmd. Python's subprocess doesn't honor PATHEXT for non-shell invocations, so it can't find the binary. Fix: use shutil.which("claude") or "claude.cmd" (or just claude.cmd if cross-platform isn't a concern — the script is Windows-or-bust without this fix anyway).

2. write_text() fails with UnicodeEncodeError on cp1252
generate_report.py and run_loop.py use .write_text() without specifying encoding. On Windows, locale.getpreferredencoding() returns cp1252 by default, which can't encode the ✗/✓ characters in the HTML report. Fix: add encoding="utf-8" to every .write_text() call (5 in run_loop.py, 1 in generate_report.py).

Tested locally — both fixes resolve the issues.

@SaluxSolutions

Copy link
Copy Markdown

Independent confirmation of these bugs from another Windows
environment, plus a related supplementary finding the same
shutil.which pattern would resolve in an adjacent file.

Where I hit them: marketplace-distributed copy of skill-creator at
anthropics/claude-plugins-official/plugins/skill-creator/skills/skill-creator/scripts/,
which mirrors the upstream source-of-truth at
anthropics/skills:skills/skill-creator/scripts/ (the diff base of
this PR).

Confirmed:

  1. Encoding bugs from missing encoding="utf-8" on Path.write_text()
    reproduces here. Windows defaults to cp1252 and HTML output mangles
    non-ASCII content (and JSON serialization can corrupt depending on
    payload).

  2. subprocess not finding the claude binary — reproduces. I
    patched this locally with the same shutil.which("claude") pattern,
    but my fallback was "claude". Your "claude.cmd" fallback is
    correct
    — on Windows, the claude shim is the .cmd wrapper, so
    plain "claude" would still fail in the unlikely event shutil.which
    returned None. Adopting yours over mine.

Supplementary finding (FWIW — not asking you to expand scope):
the same shutil.which("claude") pattern is needed in
scripts/improve_description.py, which is not in this PR's scope and
not covered by PR #1099 either. My local diff on that file:

--- a/skills/skill-creator/scripts/improve_description.py
+++ b/skills/skill-creator/scripts/improve_description.py
@@ -10,6 +10,7 @@
 import json
 import os
 import re
+import shutil
 import subprocess
 import sys
 from pathlib import Path
@@ -23,7 +24,8 @@
     Prompt goes over stdin (not argv) because it embeds the full SKILL.md
     body and can easily exceed comfortable argv length.
     """
-    cmd = ["claude", "-p", "--output-format", "text"]
+    claude_bin = shutil.which("claude") or "claude.cmd"
+    cmd = [claude_bin, "-p", "--output-format", "text"]
     if model:
         cmd.extend(["--model", model])
 

(I've already aligned the fallback with your "claude.cmd" choice
above.) Fully your call whether to fold this into this PR, leave it
for a follow-up, or skip entirely — I'm noting it here primarily so
the maintainer review has visibility, not as a request to expand
scope.

Adopt-when-merged: I'll remove my local run_eval.py patch in
favor of yours once this lands, and align improve_description.py
either with whatever this PR ships or with a follow-up.

@dmwyatt

dmwyatt commented May 24, 2026

Copy link
Copy Markdown

Independently reproduced the encoding bugs on Windows 11 (Python 3.13.4, cp1252 locale). To help make this fix comprehensive rather than whack-a-mole, here is a complete audit of locale-default text I/O across skills/skill-creator/scripts/. Every site below uses locale.getpreferredencoding(False) (cp1252 on most Windows installs) and should pin encoding="utf-8":

File Line(s) Call
utils.py 9 (skill_path / "SKILL.md").read_text()
run_eval.py 68, 272 write_text / read_text
run_loop.py 151, 261, 278, 313, 317, 321 write_text / read_text
improve_description.py 35-42 subprocess.run(..., text=True) (no encoding; sends full SKILL.md over stdin, decodes the model reply)
improve_description.py 189, 208, 211 write_text / read_text
generate_report.py 314, 319 read_text / write_text
aggregate_benchmark.py 90, 120, 142, 377, 383 open(...) for JSON/markdown read+write
quick_validate.py 22 read_text()

The most impactful one is utils.py:9: parse_skill_md is called by run_eval.py, run_loop.py, improve_description.py, and package_skill.py, so a single emoji or curly quote in a SKILL.md description crashes all of them with UnicodeDecodeError: 'charmap' codec can't decode byte .... It is not in this PR's current diff. (JSON written via json.dump/json.dumps is ASCII-safe by default, but the files are still opened in the locale encoding, so reads can fail and writes are non-portable; pinning utf-8 makes them deterministic.)

Verified on this machine that adding encoding="utf-8" at each site resolves it. Happy to share a patch covering the full set if useful.

(Separate, out of scope here: package_skill.py prints emoji to stdout, which raises UnicodeEncodeError on a cp1252 stdout. And the claude vs claude.cmd resolution this PR fixes did not reproduce on my install, where claude resolves fine, so that one appears install-dependent.)


Aside, unrelated to this PR's code: some context on how community code contributions here have been getting reviewed, for anyone weighing whether to invest effort: #1195

@hiiqbiz-wq

Copy link
Copy Markdown

Pacific (Win11 Pro 26200, Python 3.13.13, uv, claude-code 2.1.145) confirms this PR's fixes are needed even with #1099 applied — my skill description has em-dashes (), so parse_skill_md at scripts/utils.py:9 would crash on the read_text() call without the encoding="utf-8" sweep here.

#1050 and #1099 together are the full "skill-creator runs on Windows" change set. Both have multiple independent Windows repros at this point. Worth merging as a pair.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants