Skip to content

[WIP] Fix failing GitHub Actions job 70974335324 in PR #39#40

Merged
A1L13N merged 3 commits intomainfrom
copilot/fix-github-actions-failure-39
Apr 12, 2026
Merged

[WIP] Fix failing GitHub Actions job 70974335324 in PR #39#40
A1L13N merged 3 commits intomainfrom
copilot/fix-github-actions-failure-39

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 12, 2026

  • Fix src/worker.py to remove js.Object.fromEntries usage in _import_aes_key(), encrypt_aes(), and decrypt_aes()
  • Verify all 234 tests pass locally
Original prompt

Create a pull request to fix failing GitHub Actions job 70974335324 in run 24298088878 for PR #39.

Failure summary (from job logs):

  • Tests fail due to AttributeError: "'_JsModule' object has no attribute 'Object'".
  • Error originates in AES helpers using js.Object.fromEntries when building algorithm dictionaries for WebCrypto.
  • Stack traces point to src/worker.py around _import_aes_key() line ~115 and encrypt_aes()/decrypt_aes(). This causes encryption/decryption failures and cascades into API tests returning 500s and decryption errors.

Repo/ref:

  • Repository: alphaonelabs/learn
  • Failing job ref/commit: 7d147f8

What to change:

  1. Update src/worker.py to remove reliance on js.Object.fromEntries.

    • In _import_aes_key(), construct the algorithm descriptor without dict_converter=js.Object.fromEntries.
    • In encrypt_aes() and decrypt_aes(), build algo descriptors without js.Object.fromEntries; pass plain Python dicts (or to_js without dict_converter) and ensure iv/data use to_js(..., create_pyproxies=False) as appropriate.
    • Keep behavior: AES-256-GCM via js.crypto.subtle, output prefix "v1:", and XOR legacy fallback for ciphertext without prefix.
  2. Ensure unit tests pass under the GitHub Actions workflow (.github/workflows/tests.yml uses Python 3.12 running pytest).

Acceptance criteria:

  • pytest passes in CI.
  • No more AttributeError about js.Object.
  • AES tests (round trip, prefix, different plaintexts differ) pass.

Relevant files:

  • src/worker.py
  • .github/workflows/tests.yml (no changes required unless needed).

Context link:

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: Please find a solution for this failing job. Use the logs, job definition, and any referenced files where the failure occurred. Keep your response focused on the solution and include code suggestions when appropriate.

Assistant: The failures all stem from the AES helpers in src/worker.py using a JS interop pattern that doesn’t exist in the test runtime:

  • Error: AttributeError: '_JsModule' object has no attribute 'Object'
  • Triggered at:
    • src/worker.py:115 in _import_aes_key() (dict_converter=js.Object.fromEntries)
    • Also affects encrypt_aes() / decrypt_aes() and then cascades into API tests (500s, [decryption error], auth failures, etc.)

In this repo, tests run under plain CPython (.github/workflows/tests.yml), not an actual Cloudflare Workers/pyodide JS environment, so js.Object.fromEntries is not available.

Fix: remove js.Object.fromEntries and pass plain dicts/typed arrays

Update _import_aes_key(), encrypt_aes(), and decrypt_aes() to avoid referencing js.Object.* and to pass algorithm parameters in a way that works in the Workers/pyodide runtime and won’t crash the test environment’s js shim.

Suggested patch (edit src/worker.py at the referenced lines in this job’s ref: 7d147f831e0e26f0cfec7841bf9cd3bcb64ec78a):

# src/worker.py

async def _import_aes_key(key_bytes: bytes) -> object:
    """Import raw bytes as a Web Crypto AES-GCM CryptoKey."""
    key_buf = to_js(key_bytes, create_pyproxies=False)

    # Don't use js.Object.fromEntries (not present in the test/js shim).
    # A plain dict is sufficient for WebCrypto algorithm descriptors.
    algo = {"name": "AES-GCM"}

    usages = ["encrypt", "decrypt"]
    return await js.crypto.subtle.importKey("raw", key_buf, algo, False, usages)


async def encrypt_aes(plaintext: str, secret: str) -> str:
    if not plaintext:
        return ""
    try:
        key_bytes  = _derive_aes_key_bytes(secret)
        crypto_key = await _import_aes_key(key_bytes)

        iv_array = js.Uint8Array.new(12)
        js.crypto.getRandomValues(iv_array)
        iv = bytes(iv_array)

        # Pass dict directly; keep iv as the Uint8Array
        algo = {"name": "AES-GCM", "iv": iv_array}

        data   = to_js(plaintext.encode("utf-8"), create_pyproxies=False)
        ct_buf = await js.crypto.subtle.encrypt(algo, crypto_key, data)
        ct     = bytes(js.Uint8Array.new(ct_buf))
        return "v1:" + base64.b64encode(iv + ct).decode("ascii")
    except Exception as exc:
        capture_exception(exc, where="encrypt_aes")
        raise RuntimeError(f"AES-256-GCM encryption failed: {exc}") from exc


async def decrypt_aes(ciphertext: str, secret: str) -> str:
    if not ciphertext:
        return ""
    if not ciphertext.startswith("v1:"):
        return _decrypt_xor(ciphertext, secret)
    try:
        raw    = base64.b64decode(ciphertext[3:])
        iv, ct = raw[:12], raw[12:]
    except Exception as exc:
        capture_exception(exc, where="decrypt_aes.decode")
        return "[decryption error]"
    try:
        key_bytes  = _derive_aes_key_bytes(secret)
        crypto_key = await _import_aes_key(key_bytes)

        iv_array = to_js(...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created from Copilot chat.*
>

@A1L13N A1L13N marked this pull request as ready for review April 12, 2026 14:17
@cloudflare-workers-and-pages
Copy link
Copy Markdown
Contributor

cloudflare-workers-and-pages bot commented Apr 12, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
learn 8ac4409 Commit Preview URL

Branch Preview URL
Apr 12 2026, 02:19 PM

@A1L13N A1L13N merged commit 2b843c2 into main Apr 12, 2026
2 checks passed
@A1L13N A1L13N deleted the copilot/fix-github-actions-failure-39 branch April 12, 2026 14:19
Copilot AI requested a review from A1L13N April 12, 2026 14:19
Copilot stopped work on behalf of A1L13N due to an error April 12, 2026 14:19
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.

2 participants