Files
devin-ai-integration[bot] b8029973aa fix(sdk): guard egressProxy shape in JS and drop null proxy credentials (#1757)
## Summary

Follow-up to #1688. Three fixes on the `network.egressProxy` /
`network["egress_proxy"]` paths a caller reaches by bypassing the types,
plus the one changelog snippet that does not run.

**The guards disagreed.** Python raised `InvalidArgumentException` for a
proxy without a string `address`; JS had none, and since
`buildEgressProxyBody` rebuilds the body from the known fields, an
address that isn't there simply vanished and the caller got an API error
about a `{}` they never wrote. Nothing leaked — `address` is `required`
in the spec, so all of these already failed closed at the API — but the
error named the wrong thing.

```ts
function buildEgressProxyBody(egressProxy: SandboxEgressProxyOpts) {
+  if (!isPlainObject(egressProxy) || typeof egressProxy.address !== 'string') {
+    throw new InvalidArgumentError(
+      `network egressProxy must be an object with a string 'address' (e.g. 'proxy.example.com:1080').`
+    )
+  }
```

| caller passes | JS before | JS now | Python |
|---|---|---|---|
| `{}` | `{"egressProxy":{}}` | `InvalidArgumentError` |
`InvalidArgumentException` |
| `{address: 1080}` | `{"egressProxy":{"address":1080}}` |
`InvalidArgumentError` | `InvalidArgumentException` |
| `'proxy.example.com:1080'` | `{"egressProxy":{}}` — address dropped |
`InvalidArgumentError` | `InvalidArgumentException` |

**`null` credentials reached the wire.** Both SDKs checked `!==
undefined` / `in`, so a `null` / `None` username or password serialized
as a JSON null the API rejects (`type: string`). Reading a credential
out of an unset environment variable is the way to land there, and it is
the one case where the caller means "this proxy takes no credentials" —
both now skip a nullish credential (`!= null` in JS, `.get(...) is not
None` in Python).

```ts
await Sandbox.create({
  network: {
    egressProxy: {
      address: 'proxy.example.com:1080',
      // Unset in the environment; the proxy takes no credentials.
      username: process.env.PROXY_USER,
    },
  },
})
```

```python
Sandbox.create(
    network={
        "egress_proxy": {
            "address": "proxy.example.com:1080",
            "username": os.environ.get("PROXY_USER"),
        },
    },
)
```

**The published `get_info` snippet.** The 2.41.0 entry in both
changelogs printed `info.network["egress_proxy"]`, but
`SandboxInfo.network` is `Optional` and `egress_proxy` is `NotRequired`
— pyright rejects it (`reportOptionalSubscript`,
`reportTypedDictNotRequiredAccess`) and it raises at runtime for a
sandbox without a proxy, unlike the TS line right above it
(`info.network?.egressProxy`). It now reads `print((info.network or
{}).get("egress_proxy"))`.

Tests cover the three rejected JS shapes and the null credentials in
both SDKs.


Link to Devin session:
https://app.devin.ai/sessions/216bb02ad7924e4ba5f2968aaadc7938
Requested by: @mishushakov

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: mish@e2b.dev <mish@e2b.dev>
2026-08-21 20:00:22 +00:00
..
2025-08-21 08:45:25 -07:00
2025-06-05 07:10:07 -07:00
2026-08-21 15:08:58 +00:00
2026-08-21 15:08:58 +00:00
2026-08-21 15:08:58 +00:00

E2B Logo

Last 1 month downloads for the Python SDK

What is E2B?

E2B is an open-source infrastructure that allows you to run AI-generated code in secure isolated sandboxes in the cloud. To start and control sandboxes, use our JavaScript SDK or Python SDK.

Run your first Sandbox

1. Install SDK

pip install e2b

2. Get your E2B API key

  1. Sign up to E2B here.
  2. Get your API key here.
  3. Set environment variable with your API key
E2B_API_KEY=e2b_***

3. Start a sandbox and run commands

from e2b import Sandbox

with Sandbox.create() as sandbox:
    result = sandbox.commands.run('echo "Hello from E2B!"')
    print(result.stdout)  # Hello from E2B!

4. Bind the configuration to a client

The top-level Sandbox, AsyncSandbox, Volume, AsyncVolume, Template, AsyncTemplate and Secret exports read their configuration from the environment variables. To use an explicit configuration — e.g. several API keys or domains in one process — create an E2B client and use the resource classes it exposes:

from e2b import E2B

client = E2B(api_key="e2b_***", domain="e2b.dev")

sandbox = client.Sandbox.create()
volume = client.Volume.create("my-volume")
exists = client.Template.exists("my-template")
secret = client.Secret.create("openai-api-key", "sk-***")

# The async variants are exposed as well.
async_sandbox = await client.AsyncSandbox.create()

# The classes can be assigned and used like the top-level ones.
Sandbox = client.Sandbox
paginator = Sandbox.list()

Per-call params still take precedence over the client's params, and clients are isolated from each other and from the env-configured top-level exports.

5. Code execution with Code Interpreter

If you need run_code(), install the Code Interpreter SDK:

pip install e2b-code-interpreter
from e2b_code_interpreter import Sandbox

with Sandbox.create() as sandbox:
    execution = sandbox.run_code("x = 1; x += 1; x")
    print(execution.text)  # outputs 2

6. Check docs

Visit E2B documentation.

7. E2B cookbook

Visit our Cookbook to get inspired by examples with different LLMs and AI frameworks.