mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 04:27:41 +00:00
fix: guard resolveUserPath against undefined input (#10176)
* fix: guard resolveUserPath against undefined input When subagent spawner omits workspaceDir, resolveUserPath receives undefined and crashes on .trim(). Add a falsy guard that falls back to process.cwd(), matching the behavior callers already expect. Closes #10089 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: harden runner workspace fallback (#10176) (thanks @Yida-Dev) * fix: harden workspace fallback scoping (#10176) (thanks @Yida-Dev) * refactor: centralize workspace fallback classification and redaction (#10176) (thanks @Yida-Dev) * test: remove explicit any from utils mock (#10176) (thanks @Yida-Dev) * security: reject malformed agent session keys for workspace resolution (#10176) (thanks @Yida-Dev) --------- Co-authored-by: Yida-Dev <reyifeijun@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Gustavo Madeira Santana <gumadeiras@gmail.com>
This commit is contained in:
@@ -219,6 +219,75 @@ describe("runEmbeddedPiAgent", () => {
|
||||
await expect(fs.stat(path.join(agentDir, "models.json"))).resolves.toBeTruthy();
|
||||
});
|
||||
|
||||
it("falls back to per-agent workspace when runtime workspaceDir is missing", async () => {
|
||||
const sessionFile = nextSessionFile();
|
||||
const fallbackWorkspace = path.join(tempRoot ?? os.tmpdir(), "workspace-fallback-main");
|
||||
const cfg = {
|
||||
...makeOpenAiConfig(["mock-1"]),
|
||||
agents: {
|
||||
defaults: {
|
||||
workspace: fallbackWorkspace,
|
||||
},
|
||||
},
|
||||
} satisfies OpenClawConfig;
|
||||
await ensureModels(cfg);
|
||||
|
||||
const result = await runEmbeddedPiAgent({
|
||||
sessionId: "session:test-fallback",
|
||||
sessionKey: "agent:main:subagent:fallback-workspace",
|
||||
sessionFile,
|
||||
workspaceDir: undefined as unknown as string,
|
||||
config: cfg,
|
||||
prompt: "hello",
|
||||
provider: "openai",
|
||||
model: "mock-1",
|
||||
timeoutMs: 5_000,
|
||||
agentDir,
|
||||
runId: "run-fallback-workspace",
|
||||
enqueue: immediateEnqueue,
|
||||
});
|
||||
|
||||
expect(result.payloads?.[0]?.text).toBe("ok");
|
||||
await expect(fs.stat(fallbackWorkspace)).resolves.toBeTruthy();
|
||||
});
|
||||
|
||||
it("throws when sessionKey is malformed", async () => {
|
||||
const sessionFile = nextSessionFile();
|
||||
const cfg = {
|
||||
...makeOpenAiConfig(["mock-1"]),
|
||||
agents: {
|
||||
defaults: {
|
||||
workspace: path.join(tempRoot ?? os.tmpdir(), "workspace-fallback-main"),
|
||||
},
|
||||
list: [
|
||||
{
|
||||
id: "research",
|
||||
workspace: path.join(tempRoot ?? os.tmpdir(), "workspace-fallback-research"),
|
||||
},
|
||||
],
|
||||
},
|
||||
} satisfies OpenClawConfig;
|
||||
await ensureModels(cfg);
|
||||
|
||||
await expect(
|
||||
runEmbeddedPiAgent({
|
||||
sessionId: "session:test-fallback-malformed",
|
||||
sessionKey: "agent::broken",
|
||||
agentId: "research",
|
||||
sessionFile,
|
||||
workspaceDir: undefined as unknown as string,
|
||||
config: cfg,
|
||||
prompt: "hello",
|
||||
provider: "openai",
|
||||
model: "mock-1",
|
||||
timeoutMs: 5_000,
|
||||
agentDir,
|
||||
runId: "run-fallback-workspace-malformed",
|
||||
enqueue: immediateEnqueue,
|
||||
}),
|
||||
).rejects.toThrow("Malformed agent session key");
|
||||
});
|
||||
|
||||
itIfNotWin32(
|
||||
"persists the first user message before assistant output",
|
||||
{ timeout: 120_000 },
|
||||
|
||||
Reference in New Issue
Block a user