Bug Description
On Windows, the flow engine fails for any workspace containing a flow whose XML has a character outside cp1252. It surfaces as a Critical UnexpectedEngineError about a missing temp file, so nothing in the reported error points at the real cause.
quick_validate in FlowScanner/public/parse_utils.py opens each flow file and calls fp.read() without passing encoding. Python then falls back to the locale encoding, which on Windows is cp1252, so any flow containing a character that cp1252 cannot decode raises UnicodeDecodeError. The scanner logs each failure at CRITICAL and drops that flow. When no flow survives, it exits with No flow files found to scan. Exiting... and never writes the --json results file. FlowScannerCommandWrapper.runFlowScannerRules then fails reading that file.
A single curly quote is enough to trigger it. The first failing byte in our case is 0x9D, which is the third byte of U+201D RIGHT DOUBLE QUOTATION MARK (E2 80 9D) and is undefined in cp1252. Smart quotes are common in flow screen text, error messages and descriptions, so this is easy to hit on a real project.
This is a locale issue rather than a Python version issue. Python 3.11 on Windows fails the same way. Linux is unaffected because the locale there is already UTF-8, which is why this never appears in GitHub Actions.
Setting PYTHONUTF8=1 makes the identical command succeed, which confirms the cause.
Output / Logs
What the user sees:
Found 1 violation(s) across 0 file(s):
1 Critical severity violation(s) found.
UnexpectedEngineError: The engine with name 'flow' threw an unexpected error:
Error: ENOENT: no such file or directory, open
'C:\Users\<user>\AppData\Local\Temp\code-analyzer-XXXXXX\run-XXXX\flow\flowScannerResultsFile.json'
at async RunTimeFlowScannerCommandWrapper.runFlowScannerRules
(...\@salesforce\code-analyzer-flow-engine\dist\python\FlowScannerCommandWrapper.js:52:36)
at async FlowScannerEngine.runRules (...\code-analyzer-flow-engine\dist\engine.js:104:34)
The actual cause, visible only when the bundled scanner is run directly:
CRITICAL | could not quick_validate flow <repo>\force-app\main\default\flows\<flow>.flow-meta.xml
Traceback (most recent call last):
File "...\@salesforce\code-analyzer-flow-engine\FlowScanner\public\parse_utils.py", line 1419, in quick_validate
flow_data = fp.read()
File "...\Python\Python314\Lib\encodings\cp1252.py", line 23, in decode
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in position 7212: character maps to <undefined>
**STATUS: Discovering flows**
No flow files found to scan. Exiting...
Steps To Reproduce
- Use a Windows machine with a non-UTF-8 locale (a standard en-US install, cp1252).
- Create or take any flow whose XML contains a character outside cp1252. A curly quote in screen text or an error message is enough, for example an
<errorMessage> containing U+201D.
- Run
sf code-analyzer run --rule-selector flow --target path/to/that.flow-meta.xml.
- The run ends with a Critical
UnexpectedEngineError naming a missing flowScannerResultsFile.json, and no flow rules are evaluated.
To see the underlying error, invoke the bundled scanner directly from the engine folder:
cd <sf-plugins>/node_modules/@salesforce/code-analyzer-flow-engine/FlowScanner
python -m flow_scanner --debug --log_file log.txt \
--workspace workspaceFiles.txt --target targetedFiles.txt \
--queries <queryName> --json out.json
Re-running that exact command with PYTHONUTF8=1 set succeeds and writes the results file.
Expected Behavior
Flow files should be read as UTF-8 regardless of platform locale. The Metadata API writes flow XML as UTF-8 and the files themselves declare <?xml version="1.0" encoding="UTF-8"?>, so the encoding is not ambiguous.
Suggested fix: pass the encoding explicitly wherever flow source is read, for example open(path, encoding='utf-8') in quick_validate and anywhere else the scanner reads flow XML.
A second, smaller point: when no flow survives validation, the engine exits without writing the results file, so a decoding problem reaches the user as a missing-file error from the Node wrapper. Failing with the collected validation errors instead would make this class of problem self-diagnosing.
Operating System
Windows 11 Enterprise 10.0.26200
Salesforce CLI Version
@salesforce/cli/2.144.6 win32-x64 node-v24.18.0
Code Analyzer Plugin (code-analyzer) Version
5.14.0 (bundled @salesforce/code-analyzer-flow-engine 0.38.0)
Node Version
v24.18.0
Java Version
Not relevant to this engine; the failure is in the Python flow scanner.
Workaround for other Windows users until this is fixed: set PYTHONUTF8=1 in the environment before running sf code-analyzer run.
Bug Description
On Windows, the
flowengine fails for any workspace containing a flow whose XML has a character outside cp1252. It surfaces as a CriticalUnexpectedEngineErrorabout a missing temp file, so nothing in the reported error points at the real cause.quick_validateinFlowScanner/public/parse_utils.pyopens each flow file and callsfp.read()without passingencoding. Python then falls back to the locale encoding, which on Windows is cp1252, so any flow containing a character that cp1252 cannot decode raisesUnicodeDecodeError. The scanner logs each failure at CRITICAL and drops that flow. When no flow survives, it exits withNo flow files found to scan. Exiting...and never writes the--jsonresults file.FlowScannerCommandWrapper.runFlowScannerRulesthen fails reading that file.A single curly quote is enough to trigger it. The first failing byte in our case is
0x9D, which is the third byte of U+201D RIGHT DOUBLE QUOTATION MARK (E2 80 9D) and is undefined in cp1252. Smart quotes are common in flow screen text, error messages and descriptions, so this is easy to hit on a real project.This is a locale issue rather than a Python version issue. Python 3.11 on Windows fails the same way. Linux is unaffected because the locale there is already UTF-8, which is why this never appears in GitHub Actions.
Setting
PYTHONUTF8=1makes the identical command succeed, which confirms the cause.Output / Logs
What the user sees:
The actual cause, visible only when the bundled scanner is run directly:
Steps To Reproduce
<errorMessage>containing U+201D.sf code-analyzer run --rule-selector flow --target path/to/that.flow-meta.xml.UnexpectedEngineErrornaming a missingflowScannerResultsFile.json, and no flow rules are evaluated.To see the underlying error, invoke the bundled scanner directly from the engine folder:
Re-running that exact command with
PYTHONUTF8=1set succeeds and writes the results file.Expected Behavior
Flow files should be read as UTF-8 regardless of platform locale. The Metadata API writes flow XML as UTF-8 and the files themselves declare
<?xml version="1.0" encoding="UTF-8"?>, so the encoding is not ambiguous.Suggested fix: pass the encoding explicitly wherever flow source is read, for example
open(path, encoding='utf-8')inquick_validateand anywhere else the scanner reads flow XML.A second, smaller point: when no flow survives validation, the engine exits without writing the results file, so a decoding problem reaches the user as a missing-file error from the Node wrapper. Failing with the collected validation errors instead would make this class of problem self-diagnosing.
Operating System
Windows 11 Enterprise 10.0.26200
Salesforce CLI Version
@salesforce/cli/2.144.6 win32-x64 node-v24.18.0
Code Analyzer Plugin (code-analyzer) Version
5.14.0 (bundled @salesforce/code-analyzer-flow-engine 0.38.0)
Node Version
v24.18.0
Java Version
Not relevant to this engine; the failure is in the Python flow scanner.
Workaround for other Windows users until this is fixed: set
PYTHONUTF8=1in the environment before runningsf code-analyzer run.