fix(workspaces): keep the final lines of a long older setup log on the task

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
DottaandClaude committed 2026-11-10 01:19:28 -06:00
1 parent d972a0955d
commit ae9a4b7a29
2 files changed
+8 -2

No files matched your search

@@ -384,6 +384,10 @@ describe.skipIf(!support.supported)("task interruption latest run query", () =>
const text = JSON.stringify(presentation); const text = JSON.stringify(presentation);
for (let index = 0; index + 8 <= secret.length; index += 1) expect(text).not.toContain(secret.slice(index, index + 8)); for (let index = 0; index + 8 <= secret.length; index += 1) expect(text).not.toContain(secret.slice(index, index + 8));
} }
// A long older log still shows its final error line.
await db.update(heartbeatRuns).set({ error: `Execution workspace provision command "${command}" failed: ${"filler\n".repeat(800)}No such file or directory` })
.where(eq(heartbeatRuns.id, run!.id));
for (const presentation of await read()) expect(presentation?.setupFailure?.output).toMatch(/No such file or directory$/);
// A transient retry shows its setup_failed predecessor's cause. // A transient retry shows its setup_failed predecessor's cause.
const predecessorId = randomUUID(); const predecessorId = randomUUID();
await db.insert(heartbeatRuns).values({ id: predecessorId, companyId: f.companyId, agentId: run!.agentId, status: "failed", await db.insert(heartbeatRuns).values({ id: predecessorId, companyId: f.companyId, agentId: run!.agentId, status: "failed",
@@ -629,9 +629,11 @@ export async function taskInterruptionPresentations(db: Db, companyId: string, i
} }
if (presentation.setupFailure) { if (presentation.setupFailure) {
const value = safe[index]?.setupFailure; const value = safe[index]?.setupFailure;
const command = safeMessage(value?.command), message = safeMessage(value?.message); // Redact the whole text, then shorten: the output keeps its final lines, not a head slice.
const whole = (text: unknown) => typeof text === "string" ? redactCurrentUserText(text, { enabled: settings.censorUsernameInLogs }) : "";
const command = whole(value?.command), message = whole(value?.message);
const failure = value && command.trim() && message.trim() const failure = value && command.trim() && message.trim()
? boundSetupCommandFailure({ ...value, command, output: value.output == null ? null : safeMessage(value.output) || null, message }) ? boundSetupCommandFailure({ ...value, command, output: value.output == null ? null : whole(value.output) || null, message })
: null; : null;
if (failure) presentation.setupFailure = failure; if (failure) presentation.setupFailure = failure;
else delete presentation.setupFailure; else delete presentation.setupFailure;