oven-sh/bun · error · Error
BUILDKITE_AGENT_TOKEN not set and no existing buildkite-agen
Error message
BUILDKITE_AGENT_TOKEN not set and no existing buildkite-agent.cfg to reuse
What it means
scripts/agent.mjs provisions a machine as a BuildKite agent; on macOS it needs either the BUILDKITE_AGENT_TOKEN environment variable or an existing buildkite-agent.cfg to reuse. With neither, it throws before writing any launchd configuration, so you cannot accidentally register an agent with no credentials.
Source
Thrown at scripts/agent.mjs:136
--background \\
--make-pidfile \\
--stdout ${escape(agentLogPath)} \\
--stderr ${escape(agentLogPath)}"
depend() {
need net
use dns logger
}
`;
writeFile(servicePath, service, { mode: 0o755 });
await spawnSafe(["rc-update", "add", "buildkite-agent", "default"], { stdio: "inherit", privileged: true });
}
if (isMacOS) {
const queue = cliOptions.queue || getEnv("BUILDKITE_AGENT_QUEUE", false) || "test-darwin";
const token = getEnv("BUILDKITE_AGENT_TOKEN", false);
if (!token && !existsSync(cfgPath)) {
throw new Error("BUILDKITE_AGENT_TOKEN not set and no existing buildkite-agent.cfg to reuse");
}
// `install` runs via sudo, so process.env.USER is "root". The launchd
// service must run as the real login user (whose ~/Library the cfg and
// build dirs live under), and the files we write here must be owned by
// them so the service can read them.
const runAsUser = process.env.SUDO_USER || process.env.USER || "administrator";
for (const dir of [homePath, cachePath, logsPath]) {
mkdir(dir);
}
// Copy this script and its imports into homePath so the launchd plist
// doesn't depend on the checkout that ran `install` sticking around.
const srcDir = fileURLToPath(new URL(".", import.meta.url));
for (const f of ["agent.mjs", "utils.mjs"]) {
copyFileSync(join(srcDir, f), join(homePath, f));
}View on GitHub (pinned to 8c5296ac45)
Solutions
- Export the token first: BUILDKITE_AGENT_TOKEN=... (create one in BuildKite org settings > Agents)
- Point the script at an existing buildkite-agent.cfg if the machine was previously registered
- Pass sudo -E (or configure env_keep) if running the installer through sudo so the variable survives
- Also set BUILDKITE_AGENT_QUEUE if you need a queue other than the default 'test-darwin'
Example fix
# before node scripts/agent.mjs install # no token, no cfg -> throws # after export BUILDKITE_AGENT_TOKEN=... node scripts/agent.mjs install
Defensive patterns
Strategy: validation
Validate before calling
import { existsSync } from 'node:fs';
const hasToken = Boolean(process.env.BUILDKITE_AGENT_TOKEN);
if (!hasToken && !existsSync(cfgPath)) {
throw new Error('set BUILDKITE_AGENT_TOKEN (BuildKite > Agents > New Agent) before running install');
} Prevention
- Export BUILDKITE_AGENT_TOKEN in the shell/profile that runs agent.mjs
- Use sudo -E or env_keep so sudo does not strip the variable during install
- Point the script at an existing buildkite-agent.cfg to reuse prior registration
When it happens
Trigger: Running the script's install/setup command on a Mac without exporting BUILDKITE_AGENT_TOKEN and with no prior agent configuration at the expected cfgPath.
Common situations: Onboarding a new CI mac machine and forgetting the token from the BuildKite organization settings; running through sudo where the env var is stripped (env_reset); a fresh macOS runner image.
Related errors
- Buildkite token not found: set BUILDKITE_AGENT_TOKEN or gran
- ${res.status} ${job.raw_log_url}
- Dockerfile not found: ${dockerfilePath}
- Please run `make compile-ffi-test` to compile the ffi test l
- openssl failed: ${stderr}
AI-assisted analysis of oven-sh/bun@8c5296ac45 (2026-08-16).
Data as JSON: /api/errors/a79ae79961bda122.
Report an issue: GitHub.