can1357/oh-my-pi · error · Error

experiment '${experimentId}' has no runs to inherit from

Error message

experiment '${experimentId}' has no runs to inherit from

What it means

resolveArmLaunch builds a new arm by inheriting the task sample (include list / trial tasks) from existing runs of the same experiment. If store.listRuns() contains no runs whose jobName maps to this experimentId, there is nothing to inherit from, so it refuses rather than inventing a sample. This error means the experiment does not exist yet or has no recorded runs.

Source

Thrown at packages/metaharness/src/server.ts:123

		return true;
	} catch {
		return false;
	}
}

/**
 * Resolve the launch request for a new arm added to an existing experiment.
 * Inherits the experiment's benchmark, dataset, and — crucially — the exact
 * task sample from a sibling arm (its recorded `include`, else its observed
 * trial tasks) so the arm is directly comparable. Only per-arm knobs (model,
 * prewalk, role, note, extra args) come from `req`. Throws if the experiment has
 * no runs to inherit from or the arm name is taken.
 */
export function resolveArmLaunch(store: RunStore, experimentId: string, req: AddArmRequest): LaunchRequest {
	if (!req.arm || /[^\w.-]/.test(req.arm)) throw new Error("arm must be a non-empty [A-Za-z0-9_.-] token");
	if (!req.model) throw new Error("model is required");
	const siblings = store.listRuns().filter(r => experimentOf(r.jobName) === experimentId);
	if (siblings.length === 0) throw new Error(`experiment '${experimentId}' has no runs to inherit from`);
	// Template = the sibling whose recorded `include` list is the longest (the
	// fullest expression of the experiment's sample — partial re-run arms
	// record subsets); among include-less siblings, the most observed trials.
	// listRuns is newest-first so ties keep the newest.
	const strings = (v: unknown): string[] =>
		Array.isArray(v) ? v.filter((x): x is string => typeof x === "string") : [];
	const recordedInclude = (r: RunRow): string[] => strings((r.config as Partial<LaunchRequest>).include);
	const score = (r: RunRow): [number, number] => {
		const recorded = recordedInclude(r).length;
		return recorded > 0 ? [1, recorded] : [0, store.listTraces(r.jobName).length];
	};
	let template = siblings[0];
	let templateScore = score(template);
	for (const r of siblings.slice(1)) {
		const s = score(r);
		if (s[0] > templateScore[0] || (s[0] === templateScore[0] && s[1] > templateScore[1])) {
			[template, templateScore] = [r, s];
		}

View on GitHub (pinned to 9690622007)

Solutions

  1. Launch the first run of the experiment via server.launch() (or record a run) before adding arms.
  2. Verify experimentId matches the prefix used at launch: arms inherit from runs named `<experimentId>-<arm>`.
  3. List existing runs (store.listRuns()) and confirm the experiment's runs are present.
  4. If the store was wiped, re-register the experiment's original runs or restart the experiment from scratch.

Example fix

// before
server.addArm("myexp", { arm: "arm-b", model: "m2" }); // no runs yet
// after
server.launch({ benchmark: "harbor", model: "m1", jobName: "myexp-arm-a" });
server.addArm("myexp", { arm: "arm-b", model: "m2" });
Defensive patterns

Strategy: validation

Validate before calling

const siblings = store.listRuns().filter(r => experimentOf(r.jobName) === experimentId);
if (siblings.length === 0) {
  throw new Error(`launch the experiment '${experimentId}' first; addArm needs sibling runs`);
}

Try / catch

try {
  server.addArm(expId, req);
} catch (err) {
  if (err instanceof Error && err.message.includes("no runs to inherit")) {
    server.launch({ model: baselineModel, jobName: `${expId}-arm-a` });
    server.addArm(expId, req);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling addArm for an experimentId that was never launched; a typo in experimentId so experimentOf(jobName) matches nothing; all runs of the experiment were deleted from the store; calling addArm before the first launch has registered its run.

Common situations: Starting a new experiment with addArm instead of an initial launch; renaming an experiment and using the old id; wiping the jobs directory while keeping old experiment ids in scripts.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/dd81e52ef22f2bc4. Report an issue: GitHub.