Skip to content

Commit 2f15445

Browse files
committed
fix(dag): dag.start treats model.unavailable as advisory, matching the tool
The new PR->dev unit gate caught it (#371's own run): the exerciser's CI context has no resolvable model, and the environment-profile validation made model.unavailable a blocking 400 — while the workflow tool's start action asks a question instead (an HTTP caller has no such interaction; spawn fails loudly at execution time if a model never resolves). All other diagnostic classes stay blocking.
1 parent 44975d7 commit 2f15445

1 file changed

Lines changed: 16 additions & 5 deletions

File tree

  • packages/opencode/src/server/routes/instance/httpapi/handlers

packages/opencode/src/server/routes/instance/httpapi/handlers/dag.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { HttpApiBuilder } from "effect/unstable/httpapi"
66
import { InstanceHttpApi } from "../api"
77
import { InvalidRequestError, ConflictError, notFound } from "../errors"
88
import { Dag } from "@/dag/dag"
9+
import { DagValidation } from "@/dag/validation"
910
import { WorkflowAuthoring } from "@/dag/authoring"
1011
import { DagEnvironmentCatalogs } from "@/dag/environment-catalogs"
1112
import { createAdmissionRecord } from "@/dag/admission"
@@ -177,12 +178,22 @@ export const dagHandlers = HttpApiBuilder.group(InstanceHttpApi, "dag", (handler
177178
environment: { directory: session.directory, parent: session.model ?? undefined },
178179
})
179180
if (result.prepared?.action !== "start" || result.errors.length > 0) {
180-
const diagnostics = result.errors
181-
.map((diagnostic) => `- [${diagnostic.code}] ${diagnostic.path}: ${diagnostic.message}${diagnostic.hint ? ` (${diagnostic.hint})` : ""}`)
182-
.join("\n")
183-
return yield* Effect.fail(
184-
new InvalidRequestError({ message: `start rejected by workflow validation:\n${diagnostics || "no prepared graph"}` }),
181+
// Parity with the workflow tool's start action: model resolution is
182+
// advisory over HTTP — the tool asks a question (no model configured
183+
// yet), an API caller has no such interaction; the spawn path fails
184+
// loudly (failWithoutFiber) at execution time if a model never
185+
// resolves. Every other diagnostic class stays blocking.
186+
const blocking = result.errors.filter(
187+
(diagnostic) => diagnostic.code !== DagValidation.DIAGNOSTIC_CODES.modelUnavailable,
185188
)
189+
if (result.prepared?.action !== "start" || blocking.length > 0) {
190+
const diagnostics = blocking
191+
.map((diagnostic) => `- [${diagnostic.code}] ${diagnostic.path}: ${diagnostic.message}${diagnostic.hint ? ` (${diagnostic.hint})` : ""}`)
192+
.join("\n")
193+
return yield* Effect.fail(
194+
new InvalidRequestError({ message: `start rejected by workflow validation:\n${diagnostics || "no prepared graph"}` }),
195+
)
196+
}
186197
}
187198
const prepared = result.prepared
188199
const dagID = yield* dag

0 commit comments

Comments
 (0)