hexojs/hexo · error · TypeError
path must be a string!
Error message
path must be a string!
What it means
Thrown by the feed_tag helper's makeFeedTag() (lib/plugins/helper/feed_tag.ts:19). The helper builds an RSS/Atom <link> tag. If a path argument is truthy but not a string (number, object, array), it is rejected. A falsy path falls through to the config.feed branch and does not throw.
Source
Thrown at lib/plugins/helper/feed_tag.ts:19
import { url_for } from 'hexo-util';
import moize from 'moize';
import type { LocalsType } from '../../types';
const feedFn = (str = '') => {
if (str) return str.replace(/2$/, '');
return str;
};
interface Options {
title?: string;
type?: string | null;
}
function makeFeedTag(this: LocalsType, path?: string, options: Options = {}, configFeed?: any, configTitle?: string) {
const title = options.title || configTitle;
if (path) {
if (typeof path !== 'string') throw new TypeError('path must be a string!');
let type = feedFn(options.type);
if (!type) {
if (path.includes('atom')) type = 'atom';
else if (path.includes('rss')) type = 'rss';
}
const typeAttr = type ? `type="application/${type}+xml"` : '';
return `<link rel="alternate" href="${url_for.call(this, path)}" title="${title}" ${typeAttr}>`;
}
if (configFeed) {
if (configFeed.type && configFeed.path) {
if (typeof configFeed.type === 'string') {
return `<link rel="alternate" href="${url_for.call(this, configFeed.path)}" title="${title}" type="application/${feedFn(configFeed.type)}+xml">`;
}View on GitHub (pinned to 059cb17494)
Solutions
- Pass a string path: <%- feed_tag('atom.xml') %>.
- Coerce: <%- feed_tag(String(x)) %> when x may be non-string.
- If you have multiple feed paths, loop and call feed_tag once per string.
Example fix
<!-- before --> <%- feed_tag(feedConfig.path) %> <!-- after --> <%- typeof feedConfig.path === 'string' ? feed_tag(feedConfig.path) : '' %>
Defensive patterns
Strategy: type-guard
Validate before calling
if (path != null && typeof path !== 'string') {
throw new TypeError(`feed_tag path must be a string, got ${typeof path}`);
}
return hexo.extend.helper.get('feed_tag').call(hexo.locals, path); Type guard
const isFeedPath = (v: unknown): v is string => typeof v === 'string' && v.length > 0;
Prevention
- Pass literal feed paths in templates (e.g. 'atom.xml').
- Coerce dynamic values with String() and guard undefined.
- Validate config.feed.path is a string before forwarding to the helper.
When it happens
Trigger: Calling <%- feed_tag(123) %> or feed_tag(someObject) from a template; passing a parsed URL object; a variable that was expected to be a path string but resolved to a number/object.
Common situations: Theme template passing a config value that is a number or object; refactor of the helper call leaving a non-string; passing an array of paths instead of iterating.
Related errors
- name must be a string!
- name is required
- start_color is required!
- end_color is required!
- name is required
AI-assisted analysis of hexojs/hexo@059cb17494 (2026-08-12).
Data as JSON: /api/errors/fdddb994c88ca5c7.
Report an issue: GitHub.