garrytan/gstack · error
excalidraw scene has no elements array
Error message
excalidraw scene has no elements array
What it means
Thrown by __excalidrawToSvg() when the parsed scene JSON does not have an Array at scene.elements. exportToSvg requires a real array of element objects, so a missing or wrongly-typed elements field would either throw deeper or render nothing; this guard fails early with a clear message. The function deliberately does not coerce — callers must pass a valid Excalidraw scene.
Source
Thrown at lib/diagram-render/src/entry.ts:88
};
window.__mermaidToExcalidraw = async (text: string): Promise<string> => {
const { elements, files } = await parseMermaidToExcalidraw(text);
const converted = convertToExcalidrawElements(elements);
const scene = {
type: "excalidraw",
version: 2,
source: "gstack-diagram-render",
elements: converted,
appState: { viewBackgroundColor: "#ffffff" },
files: files ?? {},
};
return JSON.stringify(scene);
};
window.__excalidrawToSvg = async (sceneJson: string): Promise<string> => {
const scene = JSON.parse(sceneJson);
if (!Array.isArray(scene.elements)) throw new Error("excalidraw scene has no elements array");
const svg = await exportToSvg({
elements: scene.elements,
appState: { ...(scene.appState ?? {}), exportBackground: true },
files: scene.files ?? null,
exportPadding: 16,
});
return new XMLSerializer().serializeToString(svg);
};
/**
* SVG → PNG data URL at an explicit pixel width. Callers own the DPI math:
* targetWidthPx = placed physical width (in) × 300dpi (eng-review D6.5) —
* the bundle never guesses a viewport.
*/
/** Shared ceiling for rasterization targets (both window functions). */
const MAX_TARGET_PX = 10_000;
function assertTargetWidth(px: number): void {
if (!(px > 0 && px <= MAX_TARGET_PX)) {View on GitHub (pinned to 94993f7401)
Solutions
- Validate the scene has elements as an array before calling — log the parsed object to inspect.
- If producing scenes programmatically, always include elements: [...].
- Ensure you are passing output from __mermaidToExcalidraw, not raw mermaid text.
- If the payload was truncated in transit, re-serialize the full scene.
Example fix
// before
__excalidrawToSvg(JSON.stringify({ type: 'excalidraw' }));
// after
__excalidrawToSvg(JSON.stringify({ type: 'excalidraw', elements: [], appState: {}, files: {} })); Defensive patterns
Strategy: type-guard
Validate before calling
function assertExcalidrawScene(sceneJson: string): void {
const scene = JSON.parse(sceneJson);
if (!Array.isArray(scene.elements)) {
throw new Error('Pass a valid Excalidraw scene: { type, elements: [], appState, files }');
}
} Type guard
function isExcalidrawScene(v: unknown): v is { elements: unknown[]; [k: string]: unknown } {
return typeof v === 'object' && v !== null && Array.isArray((v as any).elements);
} Prevention
- Only pass output of __mermaidToExcalidraw to __excalidrawToSvg.
- Validate scene shape before serializing for transport.
- Unit-test round-trip mermaid→excalidraw→svg to catch pipeline regressions.
- Log the parsed scene when this fires to spot upstream changes.
When it happens
Trigger: Call window.__excalidrawToSvg(sceneJson) where sceneJson parses to an object whose elements is undefined, null, an object, a string, or absent entirely. Happens if the upstream __mermaidToExcalidraw output is mangled, a hand-built scene omits elements, or the wrong JSON is passed.
Common situations: Caller passes a mermaid text string instead of a scene object; a pipeline stage stripped elements during transformation; version-skew between the scene producer and this renderer; corrupted JSON.parse of a truncated payload.
Related errors
- pdf: --from-file ${payloadPath} is not valid JSON (${msg}).
- pdf: --from-file ${payloadPath} must be a JSON object, got $
- invalid mermaid render id: ${id}
- targetWidthPx out of range: ${px}
- Skill name is empty.
AI-assisted analysis of garrytan/gstack@94993f7401 (2026-08-12).
Data as JSON: /api/errors/11cfbe500bd995bc.
Report an issue: GitHub.