siyuan-note/siyuan · error · Error
Canvas 2D is unavailable
Error message
Canvas 2D is unavailable
What it means
GraphCanvasRenderer constructor guard: canvas.getContext("2d") returned null, so no 2D rendering context could be created for the relation graph canvas. The browser denied the context (context lost, too many contexts, headless/software rendering unavailable), and the fallback canvas renderer cannot operate.
Solutions
- Free other canvas contexts in the page and retry creating the renderer
- Verify GPU/blacklist status in the browser (about:gpu or chrome://gpu)
- Switch to a browser/environment that supports Canvas 2D
Defensive patterns
Strategy: type-guard
When it happens
Trigger: Thrown at app/src/layout/dock/graph/canvasRenderer.ts:11 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/755f3ecfc28a5c4d.
Report an issue: GitHub.
Appendix: source
Thrown at app/src/layout/dock/graph/canvasRenderer.ts:11
import {getGraphNodeColor, IGraphRenderer, IGraphRenderState} from "./renderer";
import {getGraphArrowGeometry, getGraphArrowLength, getGraphEdgeOpacity, MIN_GRAPH_EDGE_WIDTH} from "./core";
export class GraphCanvasRenderer implements IGraphRenderer {
private readonly canvas: HTMLCanvasElement;
private readonly context: CanvasRenderingContext2D;
constructor(canvas: HTMLCanvasElement) {
const context = canvas.getContext("2d");
if (!context) {
throw new Error("Canvas 2D is unavailable");
}
this.canvas = canvas;
this.context = context;
}
public render(state: IGraphRenderState) {
const width = Math.max(1, Math.round(state.width * state.devicePixelRatio));
const height = Math.max(1, Math.round(state.height * state.devicePixelRatio));
if (this.canvas.width !== width || this.canvas.height !== height) {
this.canvas.width = width;
this.canvas.height = height;
}
const context = this.context;
context.setTransform(state.devicePixelRatio, 0, 0, state.devicePixelRatio, 0, 0);
context.clearRect(0, 0, state.width, state.height);
context.lineWidth = Math.max(MIN_GRAPH_EDGE_WIDTH, state.options.linkWidth * state.camera.scale);
context.lineCap = "round";
this.drawEdgeGroup(state, false, false);View on GitHub (pinned to 8641553a1f)