jgraph/drawio-desktop · error · Error

bad arg: ${name}

Error message

bad arg: ${name}

What it means

reqStr(v, name) (src/main/electron.js:3173-3181) is the canonical string validator for renderer->main IPC arguments. It throws 'bad arg: <name>' whenever v is not a string or is the empty string. The rendererReq handler calls it on fileObject.path, path, filename, and file before any write-side action (lines 3842, 3846, 3851, 3856, 3861, 3889, 3893, 3900, 3904, 3908, 3918).

Source

Thrown at src/main/electron.js:3177

		if (c1 == '<' && c2 == 'm' && c3 == 'x')
		{
			return true;
		}
	}

	return false;
};

function isConflict(origStat, stat)
{
	return stat != null && origStat != null && stat.mtimeMs != origStat.mtimeMs;
};

function reqStr(v, name)
{
	if (typeof v !== 'string' || !v)
	{
		throw new Error('bad arg: ' + name);
	}

	return v;
}

// Returns true if `realpath` is a draft- or backup-naming variant of any path
// in blessedPaths (same directory, basename starts with DRAFT_PREFEX +
// origBasename or BKP_PREFEX + origBasename). Drafts and backups are
// derivative — drawio writes them as siblings of files the user opened.
function isDraftOrBkpOfBlessed(realpath)
{
	const dir = path.dirname(realpath);
	const base = path.basename(realpath);

	for (const blessed of blessedPaths)
	{
		if (path.dirname(blessed) !== dir) continue;

View on GitHub (pinned to 403a2cb79f)

Solutions

  1. Inspect the exact field named in the message (e.g. 'bad arg: fileObject.path') and ensure the renderer sets that field to a non-empty string before dispatch.
  2. Add a type guard in the preload/renderer layer that rejects payloads with empty required fields before they reach IPC.
  3. Log args at the rendererReq entry to confirm what was actually sent vs. what the handler expected.

Example fix

// before
electron.request({action: 'saveFile', fileObject: {path: ''}, data: xml});

// after
function assertStr(v, name) { if (typeof v !== 'string' || !v) throw new TypeError('missing ' + name); }
assertStr(fileObject.path, 'fileObject.path');
electron.request({action: 'saveFile', fileObject, data: xml});
Defensive patterns

Strategy: type-guard

Validate before calling

function reqStrLocal(v, name) {
	if (typeof v !== 'string' || v.length === 0) throw new TypeError('missing string ' + name);
	return v;
}
reqStrLocal(fileObject.path, 'fileObject.path');

Type guard

const isNonEmptyString = (v) => typeof v === 'string' && v.length > 0;

Try / catch

try { reqStr(args.path, 'path'); }
catch (e) {
	if (/^bad arg:/.test(e.message)) { /* surface a user-facing field error */ return; }
	throw e;
}

Prevention

When it happens

Trigger: An IPC request whose required string field is undefined, null, a number, an object, or '' — e.g. saveFile with fileObject.path missing, writeFile with args.path null, readFile with args.filename = ''.

Common situations: Renderer sends a stale fileObject after a 'new diagram' reset where path was cleared; a custom integration calling electron.request with the wrong field names; a payload truncated by structured-clone over the contextBridge (functions/Symbols dropped).

Related errors


AI-assisted analysis of jgraph/drawio-desktop@403a2cb79f (2026-08-13). Data as JSON: /api/errors/0e54c4e4781bbf4b. Report an issue: GitHub.