eyaltoledano/claude-task-master · error

onError must be a function

Error message

onError must be a function

What it means

The onError option must be a callable that receives streaming/parsing errors. The constructor throws if onError is truthy but not a function, so error-routing mistakes surface at construction time rather than when an error actually occurs.

Source

Thrown at src/utils/stream-parser.js:74

			throw new Error('jsonPaths is required and must be an array');
		}
		if (this.jsonPaths.length === 0) {
			throw new Error('jsonPaths array cannot be empty');
		}
		if (this.maxBufferSize <= 0) {
			throw new Error('maxBufferSize must be positive');
		}
		if (this.expectedTotal < 0) {
			throw new Error('expectedTotal cannot be negative');
		}
		if (this.estimateTokens && typeof this.estimateTokens !== 'function') {
			throw new Error('estimateTokens must be a function');
		}
		if (this.onProgress && typeof this.onProgress !== 'function') {
			throw new Error('onProgress must be a function');
		}
		if (this.onError && typeof this.onError !== 'function') {
			throw new Error('onError must be a function');
		}
		if (
			this.fallbackItemExtractor &&
			typeof this.fallbackItemExtractor !== 'function'
		) {
			throw new Error('fallbackItemExtractor must be a function');
		}
		if (this.itemValidator && typeof this.itemValidator !== 'function') {
			throw new Error('itemValidator must be a function');
		}
	}

	static defaultItemValidator(item) {
		return (
			item && item.title && typeof item.title === 'string' && item.title.trim()
		);
	}
}

View on GitHub (pinned to c0c98d367c)

Solutions

  1. Pass a function: onError: (err) => console.error(err).
  2. If you have a logger, wrap it: onError: (err) => logger.error(err).
  3. Remove onError if the default error propagation is acceptable.

Example fix

// before
new StreamParser({ jsonPaths: ['$.items'], onError: logger })
// after
new StreamParser({ jsonPaths: ['$.items'], onError: (err) => logger.error('stream parse failed', err) })
Defensive patterns

Strategy: type-guard

Validate before calling

if (options.onError != null && typeof options.onError !== 'function') {
  throw new TypeError('onError must be a function');
}

Type guard

function isCallable(v) {
  return typeof v === 'function';
}

Try / catch

try {
  return new StreamParser(options);
} catch (err) {
  if (err.message === 'onError must be a function') {
    return new StreamParser({ ...options, onError: (e) => console.error(e) });
  }
  throw err;
}

Prevention

When it happens

Trigger: new StreamParser({ jsonPaths: [...], onError: true }), onError: 'handleError' (string name), or onError set to an object like an EventEmitter or logger instance instead of a function.

Common situations: Passing a logger object intending the parser to call logger.error; passing a method reference extracted incorrectly; JSON-defined options carrying placeholder strings.

Understand the failure class

Background: "Wrong argument type", "must be a string", "expected Array or Prism::Scope": TypeError and ArgumentError when a library receives a value of the wrong type — this error's family across 28 libraries.

Related errors


AI-assisted analysis of eyaltoledano/claude-task-master@c0c98d367c (2026-08-29). Data as JSON: /api/errors/fb611ede2219df2c. Report an issue: GitHub.