{"record":{"id":"613035d4c3504556","repo":"redis/node-redis","slug":"unknown-resp-type-type-string-fromcharcode-t","errorCode":null,"errorMessage":"Unknown RESP type ${type} \"${String.fromCharCode(type)}\"","messagePattern":"Unknown RESP type (.+?) \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/client/lib/RESP/decoder.ts","lineNumber":234,"sourceCode":"        return this.#handleDecodedValue(\n          this.onReply,\n          this.#decodeSet(this.getTypeMapping(), chunk)\n        );\n\n      case RESP_TYPES.MAP:\n        return this.#handleDecodedValue(\n          this.onReply,\n          this.#decodeMap(this.getTypeMapping(), chunk)\n        );\n\n      case RESP_TYPES.PUSH:\n        return this.#handleDecodedValue(\n          this.onPush,\n          this.#decodeArray(PUSH_TYPE_MAPPING, chunk)\n        );\n\n      default:\n        throw new Error(`Unknown RESP type ${type} \"${String.fromCharCode(type)}\"`);\n    }\n  }\n\n  #handleDecodedValue(cb, value) {\n    if (typeof value === 'function') {\n      this.#next = this.#continueDecodeValue.bind(this, cb, value);\n      return true;\n    }\n\n    cb(value);\n    return false;\n  }\n\n  #continueDecodeValue(cb, next, chunk) {\n    this.#next = undefined;\n    return this.#handleDecodedValue(cb, next(chunk));\n  }\n","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/redis/node-redis/blob/90fd0652bc3f2a0a1b2f79fa9096b02a86b0ac58/packages/client/lib/RESP/decoder.ts#L216-L252","documentation":"Thrown from the default branch of the RESP3 decoder's top-level decodeReply switch. Every well-formed reply must start with a known type byte (NULL, BOOLEAN, NUMBER, DOUBLE, BIG_NUMBER, SIMPLE_STRING, BLOB_STRING, VERBATIM_STRING, SIMPLE_ERROR, BLOB_ERROR, ARRAY, SET, MAP, PUSH). An unrecognized leading byte means the byte stream is not valid RESP3 at the reply boundary. The message prints both the numeric code and its ASCII char for diagnostics.","triggerScenarios":"Connecting the client (RESP3 mode) to something that is not a Redis server; a proxy injecting non-RESP bytes; RESP2-only server where the HELLO/3 negotiation left the stream misaligned; truncated or corrupted reply mid-frame; TLS plaintext/encrypted mismatch producing garbage.","commonSituations":"Pointing the url at a wrong service port (e.g. an HTTP or stats endpoint); HAProxy/nginx misroute; rediss:// against a plaintext port or vice-versa; redis server older than 6.0 with RESP forced to 3; a custom command whose reply shape the decoder cannot parse.","solutions":["Verify the endpoint is a real Redis: redis-cli -h <host> -p <port> PING.","Stop forcing RESP: 3 in options; let the client negotiate the highest mutually supported version.","Confirm TLS settings (socket.tls / rediss://) match the server's actual mode.","If the byte is consistent and reproducible, capture it and file a client bug with the command that triggered it."],"exampleFix":"// before\nconst client = createClient({ url: 'redis://...', RESP: 3 });\n\n// after\nconst client = createClient({ url: 'redis://...' }); // let the client negotiate RESP version","handlingStrategy":"try-catch","validationCode":"import { createClient } from 'redis';\n\nasync function assertRedisEndpoint(url) {\n  const probe = createClient({ url });\n  probe.on('error', () => {});\n  await probe.connect();\n  const pong = await probe.ping();\n  await probe.disconnect();\n  if (pong !== 'PONG') throw new Error(`endpoint ${url} did not PONG`);\n}\n\nawait assertRedisEndpoint('redis://host:6379');","typeGuard":null,"tryCatchPattern":"const client = createClient({ url });\nclient.on('error', err => {\n  if (/Unknown RESP type/.test(err.message)) {\n    console.error('Stream desync detected; reconnecting', err);\n  }\n});\ntry {\n  await client.connect();\n} catch (err) {\n  // surface protocol mismatch before the app runs commands\n  throw err;\n}","preventionTips":["Validate the endpoint with redis-cli before pointing the app at it.","Do not force RESP: 3 on redis servers older than 6.0.","Keep client and server major versions aligned.","Confirm TLS mode (rediss:// vs redis://) matches the server."],"tags":["resp","protocol","decoder","connection","resp3"],"backgroundTag":null,"analyzedSha":"90fd0652bc3f2a0a1b2f79fa9096b02a86b0ac58","analyzedAt":"2026-08-11T15:37:21.243Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}