{"record":{"id":"2e2444f112ff2b21","repo":"can1357/oh-my-pi","slug":"model-is-required","errorCode":null,"errorMessage":"model is required","messagePattern":"model is required","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/metaharness/src/server.ts","lineNumber":121,"sourceCode":"\ttry {\n\t\tprocess.kill(pid, 0);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Resolve the launch request for a new arm added to an existing experiment.\n * Inherits the experiment's benchmark, dataset, and — crucially — the exact\n * task sample from a sibling arm (its recorded `include`, else its observed\n * trial tasks) so the arm is directly comparable. Only per-arm knobs (model,\n * prewalk, role, note, extra args) come from `req`. Throws if the experiment has\n * no runs to inherit from or the arm name is taken.\n */\nexport function resolveArmLaunch(store: RunStore, experimentId: string, req: AddArmRequest): LaunchRequest {\n\tif (!req.arm || /[^\\w.-]/.test(req.arm)) throw new Error(\"arm must be a non-empty [A-Za-z0-9_.-] token\");\n\tif (!req.model) throw new Error(\"model is required\");\n\tconst siblings = store.listRuns().filter(r => experimentOf(r.jobName) === experimentId);\n\tif (siblings.length === 0) throw new Error(`experiment '${experimentId}' has no runs to inherit from`);\n\t// Template = the sibling whose recorded `include` list is the longest (the\n\t// fullest expression of the experiment's sample — partial re-run arms\n\t// record subsets); among include-less siblings, the most observed trials.\n\t// listRuns is newest-first so ties keep the newest.\n\tconst strings = (v: unknown): string[] =>\n\t\tArray.isArray(v) ? v.filter((x): x is string => typeof x === \"string\") : [];\n\tconst recordedInclude = (r: RunRow): string[] => strings((r.config as Partial<LaunchRequest>).include);\n\tconst score = (r: RunRow): [number, number] => {\n\t\tconst recorded = recordedInclude(r).length;\n\t\treturn recorded > 0 ? [1, recorded] : [0, store.listTraces(r.jobName).length];\n\t};\n\tlet template = siblings[0];\n\tlet templateScore = score(template);\n\tfor (const r of siblings.slice(1)) {\n\t\tconst s = score(r);\n\t\tif (s[0] > templateScore[0] || (s[0] === templateScore[0] && s[1] > templateScore[1])) {","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/metaharness/src/server.ts#L103-L139","documentation":"resolveArmLaunch requires a per-arm model because the model is one of the few knobs NOT inherited from the experiment's sibling runs — each arm exists to compare a different model. This error means req.model was falsy (missing, empty string, or undefined).","triggerScenarios":"Calling resolveArmLaunch/addArm with { arm: 'arm-b' } and no model property; passing model: '' after a failed config lookup; building the request from env vars that are unset.","commonSituations":"Reading the model from a config file or CLI flag that defaults to undefined; typos like req.models; scripting batch arm creation where one entry omits the model.","solutions":["Set req.model to the model id the arm should run (e.g. 'anthropic/claude-sonnet-4').","Check the config/env source that supplies the model — confirm it is populated before the call.","Add a pre-call assertion: if (!req.model) throw new Error('arm model missing').","Verify you are calling resolveArmLaunch and not passing a sibling-run's model field, which is intentionally not inherited."],"exampleFix":"// before\nserver.addArm(expId, { arm: \"arm-b\" });\n// after\nserver.addArm(expId, { arm: \"arm-b\", model: \"anthropic/claude-sonnet-4\" });","handlingStrategy":"validation","validationCode":"if (!req.model || typeof req.model !== \"string\") {\n  throw new Error(\"addArm requires a model for the new arm\");\n}","typeGuard":"const hasModel = (r: { model?: string }): r is { model: string } =>\n  typeof r.model === \"string\" && r.model.length > 0;","tryCatchPattern":"try {\n  server.addArm(expId, req);\n} catch (err) {\n  if (err instanceof Error && err.message === \"model is required\") {\n    throw new Error(`arm '${req.arm}' needs a model; check config profile`, { cause: err });\n  }\n  throw err;\n}","preventionTips":["Type AddArmRequest with a required model: string field so TypeScript catches omissions.","Load model ids from a single validated config source, not ad-hoc env vars.","Assert model presence in your batch-arm script before the loop starts.","Remember the model is deliberately NOT inherited from siblings — always specify it per arm."],"tags":["validation","missing-argument"],"backgroundTag":"missing-required-parameter","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}