Automattic/harper · error · TypeError

Expected binary to be a string of url but got ${typeof binar

Error message

Expected binary to be a string of url but got ${typeof binaryUrl}.

What it means

The WorkerLinter worker script expects the first message's data array to start with a string URL pointing at the WASM binary. If e.data[0] is not a string, it throws this TypeError instead of initializing SuperBinaryModule. This validates the bootstrap handshake between WorkerLinter (main thread) and worker.ts.

Source

Thrown at packages/harper.js/src/WorkerLinter/worker.ts:13

/// <reference lib="webworker" />
import './shims';
import { SuperBinaryModule, type WasmGlueFlavor } from '../BinaryModule';
import LocalLinter from '../LocalLinter';
import Serializer, { isSerializedRequest, type SerializedRequest } from '../Serializer';

// Notify the main thread that we are ready
self.postMessage('ready');

self.onmessage = (e) => {
	const [binaryUrl, dialect, glueFlavor] = e.data;
	if (typeof binaryUrl !== 'string') {
		throw new TypeError(`Expected binary to be a string of url but got ${typeof binaryUrl}.`);
	}
	if (glueFlavor !== undefined && glueFlavor !== 'full' && glueFlavor !== 'slim') {
		throw new TypeError(`Expected glue flavor to be "full" or "slim" but got ${glueFlavor}.`);
	}
	const binary = SuperBinaryModule.create(binaryUrl, glueFlavor as WasmGlueFlavor | undefined);
	const serializer = new Serializer(binary);
	const linter = new LocalLinter({ binary, dialect });

	async function processRequest(v: SerializedRequest) {
		const { procName, args } = await serializer.deserialize(v);

		if (procName in linter) {
			// @ts-expect-error
			const res = await linter[procName](...args);
			postMessage(await serializer.serializeArg(res));
		}
	}

View on GitHub (pinned to 5fe7d5ab76)

Solutions

  1. Pass a string URL to the WASM binary, e.g. new WorkerLinter({ binary: wasmUrl }) or new WorkerLinter({ binary: new URL('./wasm.wasm', import.meta.url).toString() })
  2. If you have bytes rather than a URL, convert/upload to a URL the worker can fetch (URL.createObjectURL(new Blob([bytes])))
  3. Check WorkerLinter constructor docs for the expected binary option shape
  4. Verify the value isn't undefined due to a failed dynamic import or env variable

Example fix

// before
const linter = new WorkerLinter({ binary: await import('./harper_wasm_bg.wasm') });
// after
const linter = new WorkerLinter({ binary: new URL('./harper_wasm_bg.wasm', import.meta.url).toString() });
Defensive patterns

Strategy: type-guard

Validate before calling

const binary = new URL('./harper_wasm_bg.wasm', import.meta.url).toString();
if (typeof binary !== 'string') throw new Error('binary must be a string URL');

Type guard

function isBinaryUrl(v: unknown): v is string {
  return typeof v === 'string' && (v.startsWith('/') || v.startsWith('http') || v.startsWith('blob:') || v.startsWith('data:'));
}

Try / catch

try {
  const linter = new WorkerLinter({ binary });
  await linter.setup();
} catch (e) {
  if (e instanceof TypeError && e.message.includes('Expected binary to be a string of url')) {
    console.error('WorkerLinter binary option must be a URL string, got:', typeof binary);
  }
  throw e;
}

Prevention

When it happens

Trigger: Constructing WorkerLinter with a binary option that is not a string URL (e.g. passing an ArrayBuffer, a URL object, undefined, or a WebAssembly.Module); calling worker.postMessage manually with a malformed [binaryUrl, dialect, glueFlavor] tuple.

Common situations: Config mistakes like new WorkerLinter({ binary: wasmBytes }) instead of a URL to the .wasm asset; bundler import returning a module default rather than a URL string; forgetting to pass binary so it is undefined in dev.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of Automattic/harper@5fe7d5ab76 (2026-09-06). Data as JSON: /api/errors/88647da8af08385d. Report an issue: GitHub.