{"record":{"id":"ccda84c0d6057e0d","repo":"cheeriojs/cheerio","slug":"expected-a-string","errorCode":null,"errorMessage":"Expected a string","messagePattern":"Expected a string","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"src/index.ts","lineNumber":88,"sourceCode":"\n  return load(str, opts);\n}\n\nfunction _stringStream(\n  options: InternalOptions | undefined,\n  cb: (err: Error | null | undefined, $: CheerioAPI) => void,\n): Writable {\n  if (options?._useHtmlParser2) {\n    const parser = htmlparser2.createDocumentStream(\n      (err, document) => cb(err, load(document, options)),\n      options,\n    );\n\n    return new Writable({\n      decodeStrings: false,\n      write(chunk, _encoding, callback) {\n        if (typeof chunk !== 'string') {\n          throw new TypeError('Expected a string');\n        }\n\n        parser.write(chunk);\n        callback();\n      },\n      final(callback) {\n        parser.end();\n        callback();\n      },\n    });\n  }\n\n  options ??= {};\n  options.treeAdapter ??= htmlparser2Adapter;\n\n  if (options.scriptingEnabled !== false) {\n    options.scriptingEnabled = true;\n  }","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/cheeriojs/cheerio/blob/a1be131f9b0cef323ef0d65c5babda561413ac7d/src/index.ts#L70-L106","documentation":"cheerio's stream API (the Writable returned for streaming parsing) is created with decodeStrings: false, so every chunk written to it must already be a string. Writing a Buffer (or Uint8Array) hits the typeof chunk !== 'string' check and throws 'Expected a string'.","triggerScenarios":"Piping a Buffer-producing stream (e.g. fs.createReadStream, http response with default encoding) into cheerio's stream without setting an encoding; calling stream.write(Buffer.from('<div>')) directly.","commonSituations":"Piping fs file streams or HTTP responses into the streaming parser; forgetting stream.setEncoding('utf8') before pipe; mixing Buffer-based pipelines with cheerio's string-only writable.","solutions":["Call source.setEncoding('utf8') before piping the readable stream into cheerio","Convert Buffers to strings in a transform: .pipe(new Transform({transform(c,e,cb){cb(null,c.toString())}}))","If in the browser, decode bytes via TextDecoder before writing"],"exampleFix":"// before\nfs.createReadStream('page.html').pipe(cheerioStream);\n// after\nfs.createReadStream('page.html', { encoding: 'utf8' }).pipe(cheerioStream);","handlingStrategy":"validation","validationCode":"source.setEncoding('utf8'); // before pipe\n// or when writing manually:\nstream.write(typeof chunk === 'string' ? chunk : chunk.toString('utf8'));","typeGuard":"const isStringChunk = (c: unknown): c is string => typeof c === 'string';","tryCatchPattern":"// Prefer validation over catching: decode strings before writing.\n// If unavoidable:\ntry { stream.write(data); } catch (e) { if (e instanceof TypeError && /Expected a string/.test(e.message)) stream.write(String(data)); else throw e; }","preventionTips":["Always set an encoding on readable streams piped into cheerio","Insert a Buffer-to-string Transform in binary pipelines","Never write Uint8Array/Buffer directly to cheerio's writable"],"tags":["cheerio","stream","buffer","encoding","nodejs"],"backgroundTag":"stream-encoding-mismatch","analyzedSha":"a1be131f9b0cef323ef0d65c5babda561413ac7d","analyzedAt":"2026-08-28T13:05:26.741Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}