{"record":{"id":"0125ce6be9b25d0b","repo":"sinelaw/fresh","slug":"built-error","errorCode":null,"errorMessage":"${built.error}","messagePattern":"\\$\\{built\\.error\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/fresh-editor/plugins/orchestrator.ts","lineNumber":10419,"sourceCode":"  if (options.backend === \"ssh\") {\n    const raw = options.sshOptions;\n    const extraArgs = Array.isArray(raw)\n      ? raw.map((a) => String(a).trim()).filter((a) => a !== \"\")\n      : trimmed(raw)\n        ? trimmed(raw).split(/\\s+/)\n        : [];\n    const built = buildSshSpec({\n      ...agentOptions,\n      host: trimmed(options.host),\n      name,\n      cmd,\n      remotePath: trimmed(options.path),\n      identity: trimmed(options.identity),\n      extraArgs,\n    });\n    // The dialog keeps itself open on a bad host and shows the message; a\n    // caller gets the same message as a thrown error.\n    if (!built.ok) throw new Error(built.error);\n    return built.spec;\n  }\n\n  const requestedPath = trimmed(options.path);\n  const projectPath = requestedPath || localProjectDefault();\n  // A path the caller passed has to exist. The dialog's field completes against\n  // the filesystem, so a human sees a wrong path immediately; a caller passing\n  // `path` by hand does not, and the create would otherwise \"succeed\" into a\n  // workspace rooted at a directory that isn't there.\n  if (requestedPath && !editor.fileExists(editor.localPath(requestedPath))) {\n    throw new Error(`project path does not exist: ${requestedPath}`);\n  }\n  return buildLocalSpec({\n    ...agentOptions,\n    projectPath,\n    // \"\" ⇒ `runLocalCreate` allocates the next `<project>-N` name, the same\n    // default the dialog's placeholder shows.\n    name,","sourceCodeStart":10401,"sourceCodeEnd":10437,"githubUrl":"https://github.com/sinelaw/fresh/blob/67894ca5463dbd7a89bb31add4627c27d6b79d83/crates/fresh-editor/plugins/orchestrator.ts#L10401-L10437","documentation":"In the orchestrator plugin's create-agent path, the helper that builds a workspace spec from caller-supplied options (remote host, path, identity, extra args) returns a result object; if `built.ok` is false, its `built.error` message is thrown. This is the programmatic counterpart of the create dialog: the dialog keeps itself open and shows the message, while a scripted/API caller gets the same message as a rejected promise. Typical causes are invalid remote host/identity strings or bad extra args.","triggerScenarios":"Calling the orchestrator's create/run API (e.g. runRemoteCreate or equivalent) with options whose remote host, path, identity, or extraArgs fail spec validation in the shared builder — such as an empty or malformed host, or extraArgs that the builder rejects.","commonSituations":"Scripts/automation constructing agent-run options by hand and passing a typo'd or empty `host`; SSH identity paths that don't exist; flag strings in extraArgs the builder's validation refuses; versions where the builder gained new validation rules the caller doesn't satisfy.","solutions":["Read the thrown `built.error` message — it is the same text the dialog would show — and fix the offending option field (host/path/identity/extraArgs).","Validate options before calling: ensure host is non-empty and well-formed, identity points to an existing key file.","Use the interactive create dialog once to see which values it accepts, then mirror them in the scripted call.","If extraArgs are rejected, split or remove the flags the builder does not allow."],"exampleFix":"// before\nawait orchestrator.create({ host: \"\", path: \"/srv/app\" });\n// after\nif (!options.host) throw new Error(\"host is required for remote create\");\nawait orchestrator.create({ host: \"deploy@prod-1\", path: \"/srv/app\" });","handlingStrategy":"validation","validationCode":"function validateCreateOptions(o) {\n  const errs = [];\n  if (o.host !== undefined && !/^\\S+@?\\S+$/.test(String(o.host))) errs.push(\"host must be [user@]hostname\");\n  if (o.identity && !fs.existsSync(o.identity)) errs.push(`identity key not found: ${o.identity}`);\n  if (errs.length) throw new Error(\"invalid create options: \" + errs.join(\"; \"));\n}\nvalidateCreateOptions(options); // call before orchestrator create","typeGuard":"function isValidHost(h) { return typeof h === \"string\" && h.trim().length > 0 && !/\\s/.test(h.trim()); }","tryCatchPattern":"try {\n  const spec = await orchestrator.buildSpec(options);\n} catch (e) {\n  // message equals what the dialog would show — surface it to the user for correction\n  showCreateDialogWithPrefill(options, String(e.message));\n}","preventionTips":["Mirror the dialog's field validation in scripted calls (non-empty host, existing identity path).","Read built.error carefully — it names the exact offending option.","Test create options through the interactive dialog once before automating them.","Keep extraArgs limited to flags the builder explicitly accepts."],"tags":["validation","remote","agent-orchestration","options"],"backgroundTag":"invalid-argument-value","analyzedSha":"67894ca5463dbd7a89bb31add4627c27d6b79d83","analyzedAt":"2026-09-13T15:04:03.701Z","contentChangedAt":"2026-09-13T15:04:03.701Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}