What happened?
RunSkillScriptTool generates a Python wrapper when executing shell-based skill scripts. In the shell script path, the generated wrapper currently uses:
subprocess.run(..., capture_output=True, text=True)
without passing an explicit encoding or errors policy.
Because captured stdout/stderr are read in text mode, decoding can depend on the platform default text encoding when no encoding is supplied. On Windows environments using a non-UTF-8 default encoding such as cp936/gbk, UTF-8 bytes emitted by bash or a shell script can fail while subprocess is reading the captured stream.
In a local Windows full unit-test run, this appeared as:
UnicodeDecodeError: 'gbk' codec can't decode byte 0xff in position 47: illegal multibyte sequence
The failure caused the generated shell wrapper to lose the captured stderr path. Existing shell integration tests that expected stderr to map to warning or error instead observed success.
Affected path
RunSkillScriptTool.run_async()
-> _SkillScriptCodeExecutor.execute_script_async()
-> generated Python wrapper
-> shell script branch for .sh / .bash files
-> subprocess.run(..., capture_output=True, text=True)
-> JSON shell result envelope
-> RunSkillScriptTool parses stdout/stderr/returncode
-> result status becomes success / warning / error
Expected behavior
The generated wrapper should decode captured shell stdout/stderr with a stable encoding policy so locale differences do not prevent the wrapper from returning the JSON shell-result envelope.
Suggested fix
Use explicit UTF-8 decoding with replacement error handling for shell wrapper subprocess output:
subprocess.run(
...,
capture_output=True,
text=True,
encoding=utf-8,
errors=replace,
...
)
This keeps the existing text-mode behavior while avoiding locale-dependent decode failures. Invalid non-UTF-8 byte sequences can be represented with replacement characters so the wrapper can still return stdout, stderr, and return code to the caller.
Notes
This does not attempt to preserve arbitrary legacy-encoded shell output byte-for-byte. It is intended to make generated shell wrapper output handling stable for UTF-8 skill scripts/resources across platforms.
What happened?
RunSkillScriptToolgenerates a Python wrapper when executing shell-based skill scripts. In the shell script path, the generated wrapper currently uses:without passing an explicit
encodingorerrorspolicy.Because captured stdout/stderr are read in text mode, decoding can depend on the platform default text encoding when no encoding is supplied. On Windows environments using a non-UTF-8 default encoding such as cp936/gbk, UTF-8 bytes emitted by
bashor a shell script can fail whilesubprocessis reading the captured stream.In a local Windows full unit-test run, this appeared as:
The failure caused the generated shell wrapper to lose the captured stderr path. Existing shell integration tests that expected stderr to map to
warningorerrorinstead observedsuccess.Affected path
Expected behavior
The generated wrapper should decode captured shell stdout/stderr with a stable encoding policy so locale differences do not prevent the wrapper from returning the JSON shell-result envelope.
Suggested fix
Use explicit UTF-8 decoding with replacement error handling for shell wrapper subprocess output:
This keeps the existing text-mode behavior while avoiding locale-dependent decode failures. Invalid non-UTF-8 byte sequences can be represented with replacement characters so the wrapper can still return stdout, stderr, and return code to the caller.
Notes
This does not attempt to preserve arbitrary legacy-encoded shell output byte-for-byte. It is intended to make generated shell wrapper output handling stable for UTF-8 skill scripts/resources across platforms.