diff --git a/backend/src/workspaces/preprocessing-service.ts b/backend/src/workspaces/preprocessing-service.ts index da5d7bc6..9afe0390 100644 --- a/backend/src/workspaces/preprocessing-service.ts +++ b/backend/src/workspaces/preprocessing-service.ts @@ -129,7 +129,8 @@ export class WorkspacePreprocessingService { { kind: "runtime_config", digest: runtime.configLease.configDigest }, ], }); - } catch { + } catch (error) { + const detail = error instanceof Error ? error.message : String(error); return { schemaVersion: 1, status: "failed", @@ -139,6 +140,7 @@ export class WorkspacePreprocessingService { descriptorBlob: "", operation: "inspect", completedStages: [], + warnings: detail.length > 0 ? [detail.slice(0, 512)] : undefined, }; } } diff --git a/backend/src/workspaces/runtime-config-lease.ts b/backend/src/workspaces/runtime-config-lease.ts index 2cffe6d3..a0453622 100644 --- a/backend/src/workspaces/runtime-config-lease.ts +++ b/backend/src/workspaces/runtime-config-lease.ts @@ -337,12 +337,20 @@ export async function renderActiveWorkspaceRuntime(options: { secretRoots: readonly string[]; semanticRuntime: SemanticRuntimeConfig; }): Promise { - const { revision } = await options.registry.read(options.workspaceId); + // The persisted active state may reference host-side snapshot paths (written by another + // process or installation). Read the active state directly and resolve the immutable snapshot + // beneath this process's own configured registry root, so the path is correct inside the + // maintenance container and on the host. This deliberately bypasses WorkspaceRegistry.read, + // whose integrity check would fail on host-side paths inside the container. + const activePath = join(options.registryConfig.root, "state", "active.json"); + const active = JSON.parse(await readFileAsync(activePath, "utf8")) as { + head: string; + revisions?: Array<{ id: string; commit: string; blob: string }>; + }; + const revision = (active.revisions ?? []).find((entry) => entry.id === options.workspaceId); + if (!revision) throw new Error("workspace is not active"); const repository = new GitWorkspaceRepository(options.registryConfig); await repository.ensureLayout(); - // The persisted active state may reference host-side snapshot paths (written by another - // process or installation). The operator always resolves the immutable snapshot beneath its - // own configured registry root so the path is correct inside the container and on the host. const snapshotPath = options.registry.snapshotPath(revision.commit, revision.id); const workspace = parseWorkspaceYaml(await readFileAsync(snapshotPath, "utf8")); const rendered = renderWorkspaceRuntimeFromWorkspace({