wavetermdev/waveterm · error
source cannot be blank
Error message
source cannot be blank
What it means
The term-wsh backend handler for vdomcreatecontext requires every RPC request to carry a non-blank source identifier identifying which block/origin sent it. rh.getSource() returning blank means the caller did not attach a source, so the handler refuses to proceed rather than routing output to an unknown destination.
Source
Thrown at frontend/app/view/term/term-wsh.tsx:29
import { isBlank } from "@/util/util";
import debug from "debug";
const dlog = debug("wave:vdom");
export class TermWshClient extends WshClient {
blockId: string;
model: TermViewModel;
constructor(blockId: string, model: TermViewModel) {
super(makeFeBlockRouteId(blockId));
this.blockId = blockId;
this.model = model;
}
async handle_vdomcreatecontext(rh: RpcResponseHelper, data: VDomCreateContext) {
const source = rh.getSource();
if (isBlank(source)) {
throw new Error("source cannot be blank");
}
console.log("vdom-create", source, data);
const tabId = globalStore.get(atoms.staticTabId);
if (data.target?.newblock) {
const oref = await RpcApi.CreateBlockCommand(this, {
tabid: tabId,
blockdef: {
meta: {
view: "vdom",
"vdom:route": rh.getSource(),
},
},
magnified: data.target?.magnified,
focused: true,
});
return oref;
} else if (data.target?.toolbar?.toolbar) {
const oldVDomBlockId = globalStore.get(this.model.vdomToolbarBlockId);View on GitHub (pinned to a4447c1563)
Solutions
- Ensure the RPC is issued from a BlockController/attached context so rh.getSource() resolves to a valid block id.
- Check how the RpcResponseHelper is constructed and that its source field is populated.
- If calling programmatically, pass an explicit source/blockid in the request.
- Guard the caller: verify the source is non-blank before dispatching the RPC.
Example fix
// before
await RpcApi.VDomCreateContext(globalEnv, data); // no source context
// after
const source = getBlockSource();
if (isBlank(source)) throw new Error("vdomcreatecontext requires a source block");
await RpcApi.VDomCreateContext(makeHelper(source), data); Defensive patterns
Strategy: try-catch
Validate before calling
const source = getRpcSource(); // however the client resolves its block source
if (isBlank(source)) {
throw new Error("cannot call VDomCreateContext: no source block attached");
}
await RpcApi.VDomCreateContext(helper, data); Type guard
function hasValidSource(rh: RpcResponseHelper): boolean {
return !isBlank(rh.getSource());
} Try / catch
try {
await RpcApi.VDomCreateContext(this, data);
} catch (e) {
if (String(e.message) === "source cannot be blank") {
console.error("RPC dispatched without a source block; check block/controller context");
return;
}
throw e;
} Prevention
- Always issue block-scoped RPCs from a BlockController or context that carries a source id.
- Assert the source is set when constructing RpcResponseHelpers in tests/harnesses.
- Avoid calling block RPCs from global/shared code paths.
When it happens
Trigger: Invoking the VDomCreateContext RPC from a context with no source block set — e.g. a client constructed without a blockId/route context, a test harness, or an RPC issued before block registration so getSource() returns ""/null.
Common situations: Calling CreateBlock/VDOM commands from shared/global code outside a block controller, refactors that changed how RpcResponseHelper is constructed, or wsh calls issued from a non-block context.
Related errors
- nil wshrpc passed to wshclient
- creating new chat: %w
- adding file %s: %w
- adding context: %w
- publishing badge event: %v
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/ebeb8ca2890a1f6f.
Report an issue: GitHub.