{"record":{"id":"63d5a003902fe59f","repo":"eyaltoledano/claude-task-master","slug":"itemvalidator-must-be-a-function","errorCode":null,"errorMessage":"itemValidator must be a function","messagePattern":"itemValidator must be a function","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/utils/stream-parser.js","lineNumber":83,"sourceCode":"\t\t\tthrow new Error('expectedTotal cannot be negative');\n\t\t}\n\t\tif (this.estimateTokens && typeof this.estimateTokens !== 'function') {\n\t\t\tthrow new Error('estimateTokens must be a function');\n\t\t}\n\t\tif (this.onProgress && typeof this.onProgress !== 'function') {\n\t\t\tthrow new Error('onProgress must be a function');\n\t\t}\n\t\tif (this.onError && typeof this.onError !== 'function') {\n\t\t\tthrow new Error('onError must be a function');\n\t\t}\n\t\tif (\n\t\t\tthis.fallbackItemExtractor &&\n\t\t\ttypeof this.fallbackItemExtractor !== 'function'\n\t\t) {\n\t\t\tthrow new Error('fallbackItemExtractor must be a function');\n\t\t}\n\t\tif (this.itemValidator && typeof this.itemValidator !== 'function') {\n\t\t\tthrow new Error('itemValidator must be a function');\n\t\t}\n\t}\n\n\tstatic defaultItemValidator(item) {\n\t\treturn (\n\t\t\titem && item.title && typeof item.title === 'string' && item.title.trim()\n\t\t);\n\t}\n}\n\n/**\n * Manages progress tracking and metadata\n */\nclass ProgressTracker {\n\tconstructor(config) {\n\t\tthis.onProgress = config.onProgress;\n\t\tthis.onError = config.onError;\n\t\tthis.estimateTokens = config.estimateTokens;","sourceCodeStart":65,"sourceCodeEnd":101,"githubUrl":"https://github.com/eyaltoledano/claude-task-master/blob/c0c98d367c55296bfe69e65680625b6db437af02/src/utils/stream-parser.js#L65-L101","documentation":"The itemValidator option must be a callable used to filter/validate parsed items (the library defaults to a validator requiring a non-empty title string). The constructor throws if itemValidator is truthy but not a function.","triggerScenarios":"new StreamParser({ jsonPaths: ['$.items'], itemValidator: true }) or itemValidator set to a schema object/Zod schema instead of a predicate function.","commonSituations":"Passing a Zod/Joi schema object expecting the parser to integrate it natively; passing a validator name string; copy-paste from a library whose validator option accepts schemas.","solutions":["Pass a predicate function: itemValidator: (item) => typeof item?.id === 'string'.","If using a schema, wrap it: itemValidator: (item) => schema.safeParse(item).success.","Remove the option to use the built-in defaultItemValidator."],"exampleFix":"// before\nnew StreamParser({ jsonPaths: ['$.items'], itemValidator: itemSchema })\n// after\nnew StreamParser({ jsonPaths: ['$.items'], itemValidator: (item) => itemSchema.safeParse(item).success })","handlingStrategy":"type-guard","validationCode":"if (options.itemValidator != null && typeof options.itemValidator !== 'function') {\n  throw new TypeError('itemValidator must be a function');\n}","typeGuard":"function isPredicate(v) {\n  return typeof v === 'function';\n}","tryCatchPattern":"try {\n  return new StreamParser(options);\n} catch (err) {\n  if (err.message === 'itemValidator must be a function') {\n    return new StreamParser({ ...options, itemValidator: (item) => Boolean(item && item.title) });\n  }\n  throw err;\n}","preventionTips":["Wrap schema libraries in predicate functions: (item) => schema.safeParse(item).success.","Verify items shape matches the validator (default expects item.title as non-empty string).","Keep item shape and validator in sync via a shared type."],"tags":["configuration","validation","callbacks"],"backgroundTag":"wrong-argument-type","analyzedSha":"c0c98d367c55296bfe69e65680625b6db437af02","analyzedAt":"2026-08-29T02:56:26.071Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}