What happened

Simple Account Balancer checks GitHub for a newer release on startup. On some machines that check failed while the same machine’s browser reached GitHub without trouble, and the first version of the code failed without saying why: the user saw nothing and no reason was recorded.

The artifact

The connection raised ssl.SSLCertVerificationError, wrapped in a urllib.error.URLError.

Root cause

Python’s default certificate verification does not consult the Windows certificate store the way the browser does. When antivirus or a network filter inspects HTTPS, it installs its own root certificate that Windows trusts, so the browser accepts the connection while Python rejects it with a certificate error. The two disagree because they check against different trust stores. The app’s own comment names it: it switches to “the Windows certificate store for TLS instead of the bundled CA list, so antivirus/network filters that inject their own root cert (common on managed laptops) don’t break the GitHub update check.”

The fix

Three parts, in order.

Route verification through the Windows store before any request is made, so it trusts the same root the filter installed:

try:
    import truststore
    truststore.inject_into_ssl()
except Exception:
    pass

That block hides a second silent failure. PyInstaller does not detect truststore as a dependency, because nothing imports it at module load: it is imported inside main(). Without an explicit --hidden-import truststore in the build, the frozen app ships without truststore, the import fails, the bare except swallows it, and Python quietly falls back to its default verification. The fix looks present in the source and is silently absent from the build, so the build script has to carry the hidden import.

Third, turn the certificate failure into a message the user can act on, so the check reports the problem instead of failing quietly:

if isinstance(cause, ssl.SSLCertVerificationError):
    return (
        "GitHub's certificate could not be verified. This usually means "
        "antivirus or a network filter is inspecting HTTPS traffic."
    )

Evidence boundary

truststore changes which trust store is consulted. It does not defeat a filter that blocks the connection outright rather than inspecting it, and this path is Windows-specific. The update check only reports that a newer release exists; it never downloads or installs anything, so a failed check delays a notice rather than breaking the app.

Source ledger

Source owner Primary URL Review class Last reviewed Exact claim or evidence mapped
JDE-Projects Simple Account Balancer https://github.com/JDE-Projects/Simple-Account-Balancer/blob/2c36ac66ac20e9503dc5568167df45f79aa05c69/simple_account_balancer.py Production evidence August 18, 2026 truststore injection in main() and the SSLCertVerificationError message.
JDE-Projects Simple Account Balancer https://github.com/JDE-Projects/Simple-Account-Balancer/blob/2c36ac66ac20e9503dc5568167df45f79aa05c69/Build_Simple_Account_Balancer.bat Production evidence August 18, 2026 The –hidden-import truststore build requirement.
JDE-Projects Simple Account Balancer https://github.com/JDE-Projects/Simple-Account-Balancer/commit/79025cd8ff5fabfa333bc9440cc00821f7fb4ad7 Production evidence August 18, 2026 Reporting why the update check failed instead of failing silently.
Seth Michael Larson https://github.com/sethmlarson/truststore Framework-critical August 18, 2026 truststore exposes the operating system trust store through an ssl.SSLContext-like API.