{"record":{"id":"63a8a2a07706d431","repo":"hexojs/hexo","slug":"end-color-is-required","errorCode":null,"errorMessage":"end_color is required!","messagePattern":"end_color is required!","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"lib/plugins/helper/tagcloud.ts","lineNumber":51,"sourceCode":"\n  const min = options.min_font || 10;\n  const max = options.max_font || 20;\n  const orderby = options.orderby || 'name';\n  const order = options.order || 1;\n  const unit = options.unit || 'px';\n  const color = options.color;\n  const className = options.class;\n  const showCount = options.show_count;\n  const countClassName = options.count_class || 'count';\n  const level = options.level || 10;\n  const { transform } = options;\n  const separator = options.separator || ' ';\n  const result = [];\n  let startColor, endColor;\n\n  if (color) {\n    if (!options.start_color) throw new TypeError('start_color is required!');\n    if (!options.end_color) throw new TypeError('end_color is required!');\n\n    startColor = new Color(options.start_color);\n    endColor = new Color(options.end_color);\n  }\n\n  // Sort the tags\n  if (orderby === 'random' || orderby === 'rand') {\n    tags = tags.random();\n  } else {\n    tags = tags.sort(orderby, order);\n  }\n\n  // Limit the number of tags\n  if (options.amount) {\n    tags = tags.limit(options.amount);\n  }\n\n  const sizes = [];","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/hexojs/hexo/blob/059cb17494d0632a053c24077f5bcb6ae92acc51/lib/plugins/helper/tagcloud.ts#L33-L69","documentation":"Hexo's `tagcloud` helper (alias `tag_cloud`) renders a tag cloud. When `color: true` is set, it interpolates each tag's color along a gradient between `start_color` and `end_color` using the `Color` class (`startColor.mix(endColor, ratio)`). Both endpoints are mandatory whenever color is enabled, so Hexo throws `TypeError('end_color is required!')` if `end_color` is missing while `color` is truthy. The check runs immediately after the `start_color` check, so both messages can appear in sequence only if the first is fixed.","triggerScenarios":"Calling `<%- tagcloud({color: true, start_color: '#fff'}) %>` (or `tag_cloud(...)`) with `color: true` and `start_color` present but `end_color` omitted. The guard is `if (color) { ... if (!options.end_color) throw ... }`.","commonSituations":"Configuring a gradient and forgetting the second endpoint; YAML indentation that drops `end_color` out of the options object; setting `end_color` to an empty string (falsy and rejected); partial copy-paste of a color config.","solutions":["Supply `end_color` as a CSS color string together with `start_color`, e.g. `tagcloud({color: true, start_color: '#cccccc', end_color: '#333333'})`.","If you do not want a gradient, remove `color: true` entirely so the color branch is skipped."],"exampleFix":"// before\n<%- tagcloud({ color: true, start_color: '#cccccc' }) %>\n\n// after\n<%- tagcloud({ color: true, start_color: '#cccccc', end_color: '#333333' }) %>","handlingStrategy":"validation","validationCode":"// Validate tagcloud options before passing them to the helper.\nfunction validateTagcloudOptions(o = {}) {\n  if (o.color) {\n    if (!o.start_color) throw new TypeError('start_color is required when color is enabled');\n    if (!o.end_color) throw new TypeError('end_color is required when color is enabled');\n  }\n  return o;\n}\n\n// usage in a template-prep script:\nconst opts = validateTagcloudOptions({ color: true, start_color: '#ccc' });","typeGuard":"interface TagcloudOpts {\n  color?: boolean;\n  start_color?: string;\n  end_color?: string;\n  [k: string]: unknown;\n}\n\nfunction hasCompleteColorPair(o: TagcloudOpts): boolean {\n  return !o.color || (typeof o.start_color === 'string' && typeof o.end_color === 'string'\n    && o.start_color.length > 0 && o.end_color.length > 0);\n}\n\n// usage\nif (!hasCompleteColorPair(opts)) { /* surface a config error early */ }","tryCatchPattern":"try {\n  return tagcloud(opts);\n} catch (e) {\n  if (e instanceof TypeError && /end_color is required/.test(e.message)) {\n    hexo.log.warn('tagcloud: color enabled without end_color; disabling color');\n    return tagcloud({ ...opts, color: false });\n  }\n  throw e;\n}","preventionTips":["Treat `color`, `start_color`, and `end_color` as a single required trio in your config.","Validate option objects in a central place (e.g. a custom helper) rather than inline in templates.","Run `hexo generate` in CI to catch config errors before deploy.","Use a documented, complete tagcloud config snippet as the canonical example."],"tags":["hexo","helper","tagcloud","config","template"],"backgroundTag":null,"analyzedSha":"059cb17494d0632a053c24077f5bcb6ae92acc51","analyzedAt":"2026-08-12T20:52:05.731Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}