github/copilot-sdk · error

Invalid systemMessage.transform payload

Error message

Invalid systemMessage.transform payload

What it means

The systemMessage.transform handler requires params with a string sessionId and a non-null object sections; otherwise it throws. sections is the map of system-message sections to transform, so the library rejects anything falsy or non-object before session dispatch.

Solutions

  1. Always pass sections as an object/map of section names to content, defaulting to {} when empty.
  2. Guard the transform output before forwarding: only call the API when the result is a non-null object.
  3. Fix field naming so the sections map is not nested (params.sections.sections).
  4. Coerce primitive section values into an object wrapper.

Example fix

// before
await client.handleSystemMessageTransform({ sessionId, sections: transform(input) });
// after
const sections = transform(input);
await client.handleSystemMessageTransform({
  sessionId,
  sections: sections && typeof sections === "object" ? sections : {}
});
Defensive patterns

Strategy: validation

Validate before calling

if (!params || typeof params.sessionId !== "string" || !params.sections || typeof params.sections !== "object") {
  throw new TypeError("systemMessage.transform requires sessionId and sections object");
}

Type guard

function isSystemMessageTransformParams(p): p is { sessionId: string; sections: Record<string, unknown> } {
  return typeof p === "object" && p !== null &&
    typeof (p as any).sessionId === "string" &&
    typeof (p as any).sections === "object" && (p as any).sections !== null;
}

Try / catch

try {
  await client.handleSystemMessageTransform(params);
} catch (e) {
  if (e instanceof Error && e.message === "Invalid systemMessage.transform payload") {
    // default sections to {} and retry once
  }
}

Prevention

When it happens

Trigger: Calling the systemMessage.transform method with params null, sessionId not a string, sections undefined/null, or sections a non-object (string, number, array edge cases still pass Array check only for object typeof).

Common situations: Transform callback returning undefined and its result piped directly as params; sections built by spreading an optional config ({} lost); passing a single section string instead of the sections map.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/16a2bb6f66b63f96. Report an issue: GitHub.

Appendix: source

Thrown at nodejs/src/client.ts:3262

        if (!session) {
            throw new Error(`Session not found: ${params.sessionId}`);
        }

        const output = await session._handleHooksInvoke(params.hookType, params.input);
        return { output };
    }

    private async handleSystemMessageTransform(params: {
        sessionId: string;
        sections: Record<string, { content: string }>;
    }): Promise<{ sections: Record<string, { content: string }> }> {
        if (
            !params ||
            typeof params.sessionId !== "string" ||
            !params.sections ||
            typeof params.sections !== "object"
        ) {
            throw new Error("Invalid systemMessage.transform payload");
        }

        const session = this.sessions.get(params.sessionId);
        if (!session) {
            throw new Error(`Session not found: ${params.sessionId}`);
        }

        return await session._handleSystemMessageTransform(params.sections);
    }
}

View on GitHub (pinned to cd8cf15dc3)