hexojs/hexo · error · TypeError

name must be a string!

Error message

name must be a string!

What it means

Thrown by the partial helper (lib/plugins/helper/partial.ts:11). partial() renders a theme partial view by name. The name is used to resolve a view under the theme's getView(), so it must be a string. A non-string name is rejected before any file lookup.

Source

Thrown at lib/plugins/helper/partial.ts:11

import { dirname, join } from 'path';
import type Hexo from '../../hexo';
import type { LocalsType } from '../../types';

interface Options {
  cache?: boolean | string;
  only?: boolean;
}

export = (ctx: Hexo) => function partial(this: LocalsType, name: string, locals?: any, options: Options = {}) {
  if (typeof name !== 'string') throw new TypeError('name must be a string!');

  const { cache } = options;
  const viewDir = this.view_dir;
  const currentView = this.filename.substring(viewDir.length);
  const path = join(dirname(currentView), name);
  const view = ctx.theme.getView(path) || ctx.theme.getView(name);

  if (!view) {
    throw new Error(`Partial ${name} does not exist. (in ${currentView})`);
  }

  // Build locals lazily so a fragment cache hit does not copy the render context.
  const render = () => {
    const viewLocals: Record<string, any> = {};

    if (options.only) {
      Object.assign(viewLocals, locals);
    } else {

View on GitHub (pinned to 059cb17494)

Solutions

  1. Pass a literal string: <%- partial('header') %>.
  2. Guard dynamic names: <%- partialName ? partial(partialName) : '' %> after verifying typeof partialName === 'string'.
  3. Ensure the variable supplying the name is defined in the render context.

Example fix

<!-- before -->
<%- partial(dynamicName) %>

<!-- after -->
<%- typeof dynamicName === 'string' ? partial(dynamicName) : '' %>
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof name !== 'string') {
  throw new TypeError(`partial name must be a string, got ${typeof name}`);
}
return hexo.extend.helper.get('partial').call(hexo.locals, name);

Type guard

const isPartialName = (v: unknown): v is string => typeof v === 'string' && v.length > 0;

Prevention

When it happens

Trigger: Calling <%- partial(undefined) %> or partial(someVar) where someVar is undefined/object/number; a template variable for the partial name that was not defined in locals; passing an object expecting property access.

Common situations: Theme refactor where a partial name variable was removed but a template still references it; dynamic partial selection from front-matter with a missing field; typo in the variable name passed to partial().

Related errors


AI-assisted analysis of hexojs/hexo@059cb17494 (2026-08-12). Data as JSON: /api/errors/e8414b707d791979. Report an issue: GitHub.