Automattic/harper · error · TypeError

Expected glue flavor to be "full" or "slim" but got ${glueFl

Error message

Expected glue flavor to be "full" or "slim" but got ${glueFlavor}.

What it means

Worker bootstrap validates the optional third element of the handshake message: glueFlavor must be undefined, 'full', or 'slim'. Any other value throws this TypeError. The glue flavor selects which WASM glue (full vs slim) SuperBinaryModule should load.

Source

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

/// <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));
		}
	}

	self.onmessage = (e) => {
		if (isSerializedRequest(e.data)) {
			processRequest(e.data);

View on GitHub (pinned to 5fe7d5ab76)

Solutions

  1. Use exactly 'full', 'slim', or omit the value
  2. Fix typos and casing ('full' not 'Full')
  3. If constructing the message manually, verify element order [binaryUrl, dialect, glueFlavor]
  4. Consult the WorkerLinter docs/tests for valid WasmGlueFlavor values

Example fix

// before
new WorkerLinter({ ..., glueFlavor: 'Full' });
// after
new WorkerLinter({ ..., glueFlavor: 'full' });
Defensive patterns

Strategy: validation

Validate before calling

const GLUE_FLAVORS = ['full', 'slim'] as const;
if (glueFlavor !== undefined && !GLUE_FLAVORS.includes(glueFlavor as any)) {
  throw new Error(`glueFlavor must be 'full', 'slim', or undefined`);
}

Type guard

type WasmGlueFlavor = 'full' | 'slim';
function isGlueFlavor(v: unknown): v is WasmGlueFlavor | undefined {
  return v === undefined || v === 'full' || v === 'slim';
}

Try / catch

try {
  const linter = new WorkerLinter({ binary, glueFlavor });
  await linter.setup();
} catch (e) {
  if (e instanceof TypeError && e.message.includes('glue flavor')) {
    console.error('Invalid glueFlavor:', glueFlavor);
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing a glueFlavor other than 'full'/'slim'/undefined into WorkerLinter's worker handshake — e.g. a typo ('Full', 'full-glue'), null, a number, or hand-crafted postMessage data with extra/misordered elements so dialect lands in the glueFlavor slot.

Common situations: Typo'd enum in WorkerLinter options; manually posting [url, dialect, 'slim '] (whitespace); array destructuring off by one when constructing the handshake message yourself.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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