can1357/oh-my-pi · error · Error
arm '${req.arm}' already exists in '${experimentId}'
Error message
arm '${req.arm}' already exists in '${experimentId}' What it means
Each arm's job name is `<experimentId>-<arm>`, and the run store enforces uniqueness via store.getRun(jobName). This error means a run with that exact job name already exists, i.e. an arm with this name has already been added to the experiment. Arms are immutable labels — re-adding would collide with the existing run's directory and records.
Source
Thrown at packages/metaharness/src/server.ts:164
// Exact task sample: prefer the intended include list, else observed trial
// tasks. Trial task names are stored bare, while org-prefixed datasets
// (e.g. "swe-bench/swe-bench-verified") address tasks as "<org>/<task>" —
// re-derive the prefix for the fallback.
let include = req.include && req.include.length > 0 ? req.include : strings(cfg.include);
if (include.length === 0) {
const org = template.dataset.includes("/") ? `${template.dataset.split("/", 1)[0]}/` : "";
include = [
...new Set(
store
.listTraces(template.jobName)
.map(t => t.task)
.filter(Boolean)
.map(task => (task.includes("/") ? task : `${org}${task}`)),
),
];
}
const jobName = `${experimentId}-${req.arm}`;
if (store.getRun(jobName)) throw new Error(`arm '${req.arm}' already exists in '${experimentId}'`);
const conditions = strings(cfg.conditions);
return {
benchmark: template.benchmark,
model: req.model,
dataset: template.dataset,
include: include.length > 0 ? include : undefined,
tasks: include.length > 0 ? include.length : numberOr(cfg.tasks),
concurrency: numberOr(cfg.concurrency),
timeoutMultiplier: numberOr(cfg.timeoutMultiplier),
attempts: numberOr(cfg.attempts),
agent: str(cfg.agent),
webSearch: cfg.webSearch === true || undefined,
prebuiltBinaries: cfg.prebuiltBinaries === true || undefined,
conditions: conditions.length > 0 ? conditions : undefined,
jobName,
prewalk: req.prewalk,
role: req.role,
note: req.note,View on GitHub (pinned to 9690622007)
Solutions
- Use a new, unique arm name (e.g. append a version suffix: 'baseline-v2').
- Check existing runs first and skip the call if store.getRun(`${experimentId}-${arm}`) returns a run.
- If the old arm's run is stale/unwanted and the API supports it, remove or archive that run before re-adding.
- Make batch scripts idempotent by filtering out arm names already present in the store.
Example fix
// before
server.addArm("myexp", { arm: "baseline", model: "m2" }); // second call
// after
const arm = existing.has("myexp-baseline") ? "baseline-v2" : "baseline";
server.addArm("myexp", { arm, model: "m2" }); Defensive patterns
Strategy: validation
Validate before calling
const jobName = `${experimentId}-${req.arm}`;
if (store.getRun(jobName)) {
console.warn(`arm '${req.arm}' already present; skipping`);
return;
} Try / catch
try {
server.addArm(expId, req);
} catch (err) {
if (err instanceof Error && err.message.includes("already exists")) {
req.arm = `${req.arm}-${Date.now().toString(36)}`;
server.addArm(expId, req);
} else throw err;
} Prevention
- Make bootstrap scripts idempotent: check store.getRun(`${expId}-${arm}`) before adding.
- Version arm names (baseline-v1, baseline-v2) instead of reusing names for new configs.
- Track created arms in your own manifest to avoid duplicate calls on retries.
- On partial script failure, resume from a checkpoint rather than replaying all addArm calls.
When it happens
Trigger: Calling addArm twice with the same arm name for the same experiment; re-running an idempotent-looking script that previously created the arm; a previous failed launch that still registered the run.
Common situations: Replaying a bootstrap script after partial failure; copy-pasting addArm calls with identical arm names; wanting to re-run an arm with a new model but reusing its old name.
Related errors
- Marketplace "${catalog.name}" already exists
- run ${jobName} is already running
- Cannot register custom API "${api}": built-in API names are
- Invalid skill name "${raw}". Use lowercase letters, digits,
- Unknown tool${unknown.length === 1 ? "" : "s"} in --tools: $
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/42b063d161e413b3.
Report an issue: GitHub.