fix(engine): normalize user message content to survive malformed session state
pi-coding-agent's _getUserMessageText calls content.filter(...) on user messages; if a message lands in state.messages with content === undefined (string or array expected), the library throws "Cannot read properties of undefined (reading 'filter')", which gets caught and stored on session.state.errorMessage and rethrown without a stack. Fusion's existing message-content guard already normalized assistant/toolResult messages — extend it to user messages as well, and sweep state.messages once when the guard is installed so content loaded from a session file is repaired before the first event fires. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -477,12 +477,23 @@ function normalizeAssistantOrToolResultMessage(message: unknown): message is Rec
|
||||
}
|
||||
|
||||
const role = (message as Record<string, unknown>).role;
|
||||
if (role !== "assistant" && role !== "toolResult") {
|
||||
if (role !== "assistant" && role !== "toolResult" && role !== "user") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Array.isArray((message as Record<string, unknown>).content)) {
|
||||
(message as Record<string, unknown>).content = [];
|
||||
const obj = message as Record<string, unknown>;
|
||||
// `user` messages may carry content as a string (plain prompt) — leave those alone.
|
||||
// For any other shape (undefined, null, object, etc.) coerce to an empty array so
|
||||
// pi-coding-agent's _getUserMessageText (content.filter(...)) can't crash.
|
||||
if (role === "user") {
|
||||
if (typeof obj.content !== "string" && !Array.isArray(obj.content)) {
|
||||
obj.content = [];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!Array.isArray(obj.content)) {
|
||||
obj.content = [];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -549,6 +560,16 @@ function installMessageContentGuard(session: AgentToolHookSession, sessionManage
|
||||
return;
|
||||
}
|
||||
|
||||
// Sweep any pre-existing state.messages (e.g. restored from a session file)
|
||||
// so messages with malformed content can't crash pi-coding-agent's
|
||||
// _getUserMessageText / similar array traversals before our event hooks fire.
|
||||
const existingMessages = session.agent?.state?.messages;
|
||||
if (Array.isArray(existingMessages)) {
|
||||
for (const candidate of existingMessages) {
|
||||
normalizeAssistantOrToolResultMessage(candidate);
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof session.subscribe === "function") {
|
||||
session.subscribe((event: unknown) => {
|
||||
if (!event || typeof event !== "object" || (event as { type?: string }).type !== "message_end") {
|
||||
|
||||
Reference in New Issue
Block a user