Dashboard › opencode › Distillation
213090a4-255f-405d-b5ff-e90da3f3070d["lore_tm_v1_TPoKWVCu0mDs3oMaRHIUa24egayVOY9aZJszuRUB7ZI","lore_tm_v1_nj0gHwcYV58Lq3-5IN1pCfXnBn-RL3vDsVyxSga1dmg","lore_tm_v1_WHkIKulqfPghCTLbjrHzifHWyc4Uwg-47z7h71NKTH4","lore_tm_v1_OsIY2qDkvOaMfyeevC9j-K9sGpnJNGawBnTQ0OS7PbU","lore_tm_v1_p9xxVD8b_rweRiIJjf_uExj3vwtwuH_5aCHXYnd7Orc"]
Date: Sep 14, 2026
/home/byk/Code/opencode/packages/opencode/src/server/routes/instance/httpapi/server.ts:271-312 defines createRoutes(corsOptions?) by merging, in order, rootApiRoutes, eventApiRoutes, ptyConnectApiRoutes, instanceRoutes, serverRoutes, docRoute, and uiRoute; it then provides errorLayer, compressionLayer, corsVaryFix, fenceLayer, cors(corsOptions), AppNodeBuilderV1.build(MoveSession.node, [[LocationServiceMap.node, locationServiceMapV2]]), and HttpServer.layerServices, followed by CorsConfig, sessionLocationLayer, locationLayer, PtyEnvironment.layer, the SessionV2.node application graph, locationServiceMapV2, AppNodeBuilderV1.build(app), and finally Layer.provideMerge(Observability.layer).Observability.layer in /home/byk/Code/opencode/packages/opencode/src/server/routes/instance/httpapi/server.ts:307-311 is intentional because layers provided later build beneath earlier layers; otherwise eagerly forked fibers such as the ModelsDev background refresh capture Effectβs default stdout logger and corrupt the TUI, tracked as #34730./home/byk/Code/opencode/packages/opencode/src/server/routes/instance/httpapi/server.ts:317-322 creates its lazy webHandler with HttpRouter.toWebHandler(routes, { disableLogger: true, memoMap, middleware: disposeMiddleware }); the file exports HttpApiApp via export * as HttpApiApp from "./server".HttpApiBuilder.group(...); SSE handlers return HttpServerResponse.stream(...) and annotate success with HttpApiSchema.asText({ contentType: "text/event-stream" }). Declared raw-request/response or WebSocket routes should use handleRaw(...); raw HttpRouter.use(...) is reserved for routes outside the declared API surface, such as catch-all UI fallback.Effect.provide(SomeLayer) inside handlers or raw callbacks. HttpRouter.provideRequest(...) is only for intentionally request-level dependencies, while middleware may use Effect.provideService(...) for request-derived contexts such as WorkspaceRouteContext, InstanceRef, or WorkspaceRef.Schema.ErrorClass contracts on endpoints; built-in HttpApiError.* should be used only when their empty/tagged body is the desired wire shape. SDK-visible errors with messages need exact API error schemas such as ApiNotFoundError; domain/storage services remain free of HttpApi types, with expected errors translated at handler boundaries./home/byk/Code/opencode/packages/server/src/handlers/session.ts defines DefaultSessionsLimit = 50 and DefaultSessionHistoryLimit = 50; SessionHandler is an HttpApiBuilder.group(Api, "server.session", ...) that yields SessionV2.Service once and closes over it for all endpoint implementations.session.list parses ctx.query.cursor with SessionsCursor.parse, maps parse failures to InvalidCursorError({ message: "Invalid cursor" }), sets workspaceID: query.workspace, and defaults limit to 50. It returns sessions plus previous and next cursors anchored respectively to the first and last sessions using each sessionβs id, DateTime.toEpochMillis(session.time.created), and directions "previous" or "next".session.create passes id, agent, and model from the payload and defaults location to { directory: AbsolutePath.make(process.cwd()) }; session.active converts yield* session.active into an object mapping each sessionID to { type: "running" }.session.get, session.switchAgent, and session.switchModel translate "Session.NotFoundError" into SessionNotFoundError with sessionID and message Session not found: ${error.sessionID}; successful switch operations return HttpApiSchema.NoContent.make().session.prompt forwards sessionID, id, prompt, delivery, and resume. It maps "Session.NotFoundError" to SessionNotFoundError and "Session.PromptConflictError" to ConflictError with message Prompt message ID conflicts with an existing durable record: ${error.messageID} and resource: error.messageID.session.compact and session.wait return no content on success. Both translate "Session.NotFoundError" to SessionNotFoundError and "Session.OperationUnavailableError" to ServiceUnavailableError with message Session ${error.operation} is not available yet and service session.${error.operation}.session.revert.stage forwards merged params and payload, maps "Session.NotFoundError" and "Session.MessageNotFoundError" to public typed errors, and handles "Snapshot.Error" by generating ref = "err_" + crypto.randomUUID().slice(0, 8), logging "failed to stage session revert" with { cause: error }, then failing with UnknownError({ message: "Unexpected server error. Check server logs for details.", ref }).session.revert.clear maps "Session.NotFoundError" similarly and handles "Snapshot.Error" with an 8-character UUID-derived err_ reference, log message "failed to clear session revert" and { cause: error }, then the same public UnknownError; session.revert.commit only translates "Session.NotFoundError". Clear and commit return HttpApiSchema.NoContent.make().session.context maps "Session.NotFoundError" to SessionNotFoundError. On "Session.MessageDecodeError", it generates an err_ reference from the first 8 UUID characters, logs "failed to decode session message", annotates logs with { ref, sessionID: error.sessionID, messageID: error.messageID }, and returns the generic public UnknownError.session.history forwards sessionID, after, and a default limit of 50, then maps the page to { data: page.events, hasMore: page.hasMore } and translates "Session.NotFoundError" to SessionNotFoundError.session.events returns session.events({ sessionID: ctx.params.sessionID, after: ctx.query.after }).pipe(Stream.orDie) inside Effect.succeed; session.interrupt calls session.interrupt(sessionID) and returns no content.session.message returns { data: message } when session.message(ctx.params) finds a record; otherwise it directly yields MessageNotFoundError with sessionID, messageID, and message Message not found: ${ctx.params.messageID}.resume/runner behavior returned at least 100 matches and was truncated. In /home/byk/Code/opencode/packages/core/test/session-runner.test.ts, tests repeatedly enqueue prompts with resume: false and explicitly call session.resume(sessionID); visible cases also exercise resume failure via Effect.flip/Effect.exit, concurrent execution via Effect.forkChild, interrupted provider turns with error { type: "unknown", message: "Provider turn interrupted" }, and interrupted tool fragments whose state becomes { status: "error" }.