{"record":{"id":"6062a8144fa83419","repo":"hexojs/hexo","slug":"type-is-required","errorCode":null,"errorMessage":"type is required","messagePattern":"type is required","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"lib/extend/filter.ts","lineNumber":65,"sourceCode":"      }\n    }\n\n    if (typeof fn !== 'function') throw new TypeError('fn must be a function');\n\n    type = typeAlias[type as string] || type;\n    priority = priority == null ? 10 : priority;\n\n    const store = this.store[type as string] || [];\n    this.store[type as string] = store;\n\n    fn.priority = priority;\n    store.push(fn);\n\n    store.sort((a, b) => a.priority - b.priority);\n  }\n\n  unregister(type: string, fn: StoreFunction): void {\n    if (!type) throw new TypeError('type is required');\n    if (typeof fn !== 'function') throw new TypeError('fn must be a function');\n\n    type = typeAlias[type] || type;\n\n    const list = this.list(type);\n    if (!list || !list.length) return;\n\n    const index = list.indexOf(fn);\n\n    if (index !== -1) list.splice(index, 1);\n  }\n\n  exec(type: string, data: any, options: FilterOptions = {}): Promise<any> {\n    const filters = this.list(type);\n    if (filters.length === 0) return Promise.resolve(data);\n\n    const ctx = options.context;\n    const args = options.args || [];","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/hexojs/hexo/blob/059cb17494d0632a053c24077f5bcb6ae92acc51/lib/extend/filter.ts#L47-L83","documentation":"Thrown by Filter.unregister when the 'type' argument is falsy. Unregistration needs the filter type (e.g. 'after_post_render') to locate the correct list; an empty type has nothing to match against.","triggerScenarios":"Calling hexo.extend.filter.unregister('', fn) or unregister(undefined, fn).","commonSituations":"A plugin's teardown path passes a type variable that was never set, or iterates a list producing empty types.","solutions":["Pass a non-empty filter type string.","Guard with a truthiness check before calling unregister.","Confirm the type matches an alias used at registration time."],"exampleFix":"// before\nhexo.extend.filter.unregister(typeVar, fn);\n// after\nif (typeVar) hexo.extend.filter.unregister(typeVar, fn);","handlingStrategy":"validation","validationCode":"if (!type) throw new Error('filter type required');\nhexo.extend.filter.unregister(type, fn);","typeGuard":"const isValidType = (t: unknown): t is string => typeof t === 'string' && t.length > 0;","tryCatchPattern":null,"preventionTips":["Store the type string used at registration and reuse it for unregister.","Guard teardown loops against empty type values.","Pair every unregister with its registration in tests."],"tags":["filter","validation","plugin"],"backgroundTag":null,"analyzedSha":"059cb17494d0632a053c24077f5bcb6ae92acc51","analyzedAt":"2026-08-12T20:52:05.731Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}