sinelaw/fresh · error
${built.error}
Error message
${built.error} What it means
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.
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.
Example fix
// before
await orchestrator.create({ host: "", path: "/srv/app" });
// after
if (!options.host) throw new Error("host is required for remote create");
await orchestrator.create({ host: "deploy@prod-1", path: "/srv/app" }); Defensive patterns
Strategy: validation
Validate before calling
function validateCreateOptions(o) {
const errs = [];
if (o.host !== undefined && !/^\S+@?\S+$/.test(String(o.host))) errs.push("host must be [user@]hostname");
if (o.identity && !fs.existsSync(o.identity)) errs.push(`identity key not found: ${o.identity}`);
if (errs.length) throw new Error("invalid create options: " + errs.join("; "));
}
validateCreateOptions(options); // call before orchestrator create Type guard
function isValidHost(h) { return typeof h === "string" && h.trim().length > 0 && !/\s/.test(h.trim()); } Try / catch
try {
const spec = await orchestrator.buildSpec(options);
} catch (e) {
// message equals what the dialog would show — surface it to the user for correction
showCreateDialogWithPrefill(options, String(e.message));
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- project path does not exist
- workspace creation failed
- folder name must not be empty
- empty path
- could not open from container
AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13).
Data as JSON: /api/errors/0125ce6be9b25d0b.
Report an issue: GitHub.
Appendix: source
Thrown at crates/fresh-editor/plugins/orchestrator.ts:10419
if (options.backend === "ssh") {
const raw = options.sshOptions;
const extraArgs = Array.isArray(raw)
? raw.map((a) => String(a).trim()).filter((a) => a !== "")
: trimmed(raw)
? trimmed(raw).split(/\s+/)
: [];
const built = buildSshSpec({
...agentOptions,
host: trimmed(options.host),
name,
cmd,
remotePath: trimmed(options.path),
identity: trimmed(options.identity),
extraArgs,
});
// The dialog keeps itself open on a bad host and shows the message; a
// caller gets the same message as a thrown error.
if (!built.ok) throw new Error(built.error);
return built.spec;
}
const requestedPath = trimmed(options.path);
const projectPath = requestedPath || localProjectDefault();
// A path the caller passed has to exist. The dialog's field completes against
// the filesystem, so a human sees a wrong path immediately; a caller passing
// `path` by hand does not, and the create would otherwise "succeed" into a
// workspace rooted at a directory that isn't there.
if (requestedPath && !editor.fileExists(editor.localPath(requestedPath))) {
throw new Error(`project path does not exist: ${requestedPath}`);
}
return buildLocalSpec({
...agentOptions,
projectPath,
// "" ⇒ `runLocalCreate` allocates the next `<project>-N` name, the same
// default the dialog's placeholder shows.
name,View on GitHub (pinned to 67894ca546)