Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-team-id-env-override.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@e2b/cli": patch
---

Fix CLI team ID resolution when E2B_API_KEY is set via environment variable. Add E2B_TEAM_ID env var support. Previously, the CLI always used the team ID from ~/.e2b/config.json, causing "Team ID param mismatch" errors when the API key belonged to a different team.
23 changes: 23 additions & 0 deletions packages/cli/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { asBold, asPrimary } from './utils/format'

export let apiKey = process.env.E2B_API_KEY
export let accessToken = process.env.E2B_ACCESS_TOKEN
export const teamId = process.env.E2B_TEAM_ID

const authErrorBox = (keyName: string) => {
let link
Expand Down Expand Up @@ -82,6 +83,28 @@ export function ensureAccessToken() {
}
}

/**
* Resolve team ID with proper precedence:
* 1. CLI --team flag
* 2. E2B_TEAM_ID env var
* 3. Local e2b.toml team_id (if provided)
* 4. ~/.e2b/config.json teamId (only if E2B_API_KEY env var is NOT set,
* to avoid mismatch between env var API key and config file team ID)
*/
export function resolveTeamId(
cliTeamId?: string,
localConfigTeamId?: string
): string | undefined {
if (cliTeamId) return cliTeamId
if (teamId) return teamId
if (localConfigTeamId) return localConfigTeamId
if (!process.env.E2B_API_KEY) {
const config = getUserConfig()
return config?.teamId
}
return undefined
}

const userConfig = getUserConfig()

export const connectionConfig = new e2b.ConnectionConfig({
Expand Down
14 changes: 8 additions & 6 deletions packages/cli/src/commands/template/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import * as commander from 'commander'
import * as e2b from 'e2b'
import * as fs from 'fs'
import * as path from 'path'
import { client, connectionConfig, ensureAccessToken } from 'src/api'
import {
client,
connectionConfig,
ensureAccessToken,
resolveTeamId,
} from 'src/api'
import { configName, getConfigPath, loadConfig, saveConfig } from 'src/config'
import {
defaultDockerfileName,
Expand Down Expand Up @@ -288,13 +293,9 @@ Migration guide: ${asPrimary('https://e2b.dev/docs/template/migration-v2')}`
readyCmd = opts.readyCmd || config.ready_cmd
cpuCount = opts.cpuCount || config.cpu_count
memoryMB = opts.memoryMb || config.memory_mb
teamID = opts.team || config.team_id
}

const userConfig = getUserConfig()
if (userConfig) {
teamID = teamID || userConfig.teamId
}
teamID = resolveTeamId(opts.team, config?.team_id)

if (config && templateID && config.template_id !== templateID) {
// error: you can't specify different ID than the one in config
Expand Down Expand Up @@ -444,6 +445,7 @@ Migration guide: ${asPrimary('https://e2b.dev/docs/template/migration-v2')}`
cwd: root,
})
} catch (err: any) {
const userConfig = getUserConfig()
await buildWithProxy(
userConfig,
connectionConfig,
Expand Down
8 changes: 2 additions & 6 deletions packages/cli/src/commands/template/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ import { getRoot } from 'src/utils/filesystem'
import { listSandboxTemplates } from './list'
import { getPromptTemplates } from 'src/utils/templatePrompt'
import { confirm } from 'src/utils/confirm'
import { client } from 'src/api'
import { client, resolveTeamId } from 'src/api'
import { handleE2BRequestError } from '../../utils/errors'
import { getUserConfig } from 'src/user'

async function deleteTemplate(templateID: string) {
const res = await client.api.DELETE('/templates/{templateID}', {
Expand Down Expand Up @@ -84,10 +83,7 @@ export const deleteCommand = new commander.Command('delete')
template_id: template,
})
} else if (opts.select) {
const userConfig = getUserConfig()
if (userConfig) {
teamId = teamId || userConfig.teamId
}
teamId = resolveTeamId(teamId)

const allTemplates = await listSandboxTemplates({
teamID: teamId,
Expand Down
6 changes: 2 additions & 4 deletions packages/cli/src/commands/template/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import * as e2b from 'e2b'

import { listAliases } from '../../utils/format'
import { sortTemplatesAliases } from 'src/utils/templateSort'
import { client, ensureAccessToken } from 'src/api'
import { client, ensureAccessToken, resolveTeamId } from 'src/api'
import { teamOption } from '../../options'
import { handleE2BRequestError } from '../../utils/errors'
import { getUserConfig } from '../../user'

export const listCommand = new commander.Command('list')
.description('list sandbox templates')
Expand All @@ -17,12 +16,11 @@ export const listCommand = new commander.Command('list')
.action(async (opts: { team: string; format: string }) => {
try {
const format = opts.format || 'pretty'
const userConfig = getUserConfig()
ensureAccessToken()
process.stdout.write('\n')

const templates = await listSandboxTemplates({
teamID: opts.team || userConfig?.teamId,
teamID: resolveTeamId(opts.team),
})

for (const template of templates) {
Expand Down
8 changes: 2 additions & 6 deletions packages/cli/src/commands/template/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ import { getRoot } from 'src/utils/filesystem'
import { listSandboxTemplates } from './list'
import { getPromptTemplates } from 'src/utils/templatePrompt'
import { confirm } from 'src/utils/confirm'
import { client } from 'src/api'
import { client, resolveTeamId } from 'src/api'
import { handleE2BRequestError } from '../../utils/errors'
import { getUserConfig } from 'src/user'

async function publishTemplate(templateID: string, publish: boolean) {
const res = await client.api.PATCH('/v2/templates/{templateID}', {
Expand Down Expand Up @@ -69,10 +68,7 @@ async function templateAction(
template_id: template,
})
} else if (opts.select) {
const userConfig = getUserConfig()
if (userConfig) {
teamId = teamId || userConfig.teamId
}
teamId = resolveTeamId(teamId)

const allTemplates = await listSandboxTemplates({
teamID: teamId,
Expand Down
Loading