Skip to content

Review checklist

This is the checklist to run down — by eye, on any diff, yours or an AI’s — after the tools in Verification Tools have run and come back clean. It fits on one printed page on purpose: a checklist nobody actually opens during a review is worthless. Every line links the catalog entry that explains why, so this page stays a list, not a re-run of the course. The groups follow the same order as How to read Kafka code you did not write, plus a final Tooling group covering how each of the other seven actually gets verified.

flowchart LR
  A["Client &amp; versions"] --> T["Mostly human review<br/>(silently-ignored keys, unmaintained defaults)"]
  W["Producer"] --> P["Partial: tsc catches nothing here,<br/>only a real send reveals the gap"]
  S["Consumer loop &amp; commits"] --> R["Needs a real restart or timeout to surface"]
  N["Delivery &amp; transactions"] --> R
  ST["Topic &amp; broker config"] --> M["Accepted, not rejected --<br/>--describe/--under-min-isr-partitions shows it"]
  Sec["Ops &amp; security"] --> T2["CLI/broker rejects outright --<br/>easiest group to catch mechanically"]
  O["Connect/Streams/Schema"] --> M2["REST /config/validate + /connector-plugins,<br/>not source-vs-sink semantics"]
What actually catches each group, if anything
  • Does the code import kafkajs or @confluentinc/kafka-javascript — and does the reviewer know which one before judging any default? See the AI Bug Catalog, entry 3.
  • Does a KafkaJS config object carry a Java-client-only key (group.protocol=consumer, KIP-848) that gets silently dropped rather than rejected? See entry 2.
  • Does any shell script pass --zookeeper to a kafka-*.sh tool? Removed outright in Kafka 4.0. See entry 1.
  • Does a comment assume every compression codec or the “sticky” partition assigner ships natively on KafkaJS, when it ships only gzip and only RoundRobinAssigner? See entry 3.
  • Is idempotent: true ever set explicitly on a producer whose writes matter, rather than left at KafkaJS’s real default of false? See the AI Bug Catalog, entry 4, and Idempotent Producer.
  • Does a comment claim a compression codec (lz4, snappy, zstd) that KafkaJS does not ship a real implementation for? See entry 5.
  • Does a producer built with transactionalId ever call plain .send() directly, instead of wrapping every write in .transaction()? See entry 6.
  • Does anything slow — an HTTP call, an unbounded DB write — run inside eachMessage, forgetting that KafkaJS’s heartbeat only fires after the handler returns? See the AI Bug Catalog, entry 7, proven with a real coordinator is not aware of this member eviction, and Consumer API.
  • Does a manual commitOffsets call pass the offset just read, instead of offset + 1? See entry 8, proven with a real duplicate on restart.
  • Once a record is routed to a dead-letter topic, does the code commit the original message’s offset? See entry 9, proven with a real permanent reprocessing loop.
  • Does a consume-transform-produce loop commit its consumer offset with a separate commitOffsets call, instead of txn.sendOffsets() inside the same transaction? See the AI Bug Catalog, entry 10, proven with a real post-crash duplicate, and Exactly-Once Processing.
  • Was readUncommitted ever flipped to true to “fix” records that were, in fact, deliberately aborted? See entry 11.
  • Does retry/abort logic check error.retriable before deciding to retry, or does it retry a fenced, fatal error forever? See entry 12, proven with a real retriable: false fencing error.
  • Does a topic’s replication-factor actually support the min.insync.replicas it sets — or is the combination accepted silently per KIP-579? See the AI Bug Catalog, entry 13, and Acks and Durability.
  • Does adding partitions to an already-keyed topic happen with a plan for readers relying on per-key ordering — and does every long-lived producer/consumer client get a metadata refresh? See entry 14.
  • Is auto.create.topics.enable (or any other static broker config) ever assumed to take effect from a live kafka-configs.sh --alter call? See entry 15, proven with a real InvalidRequestException.
  • Does any script or runbook reference a CLI tool that does not exist (kafka-metadata.sh)? See the AI Bug Catalog, entry 16, proven with a real “no such file” error.
  • Does any command pass a flag that does not exist on the real tool (--run-all)? See entry 17, proven with a real UnrecognizedOptionException.
  • Does a runbook call kafka-acls.sh on a cluster that never configured authorizer.class.name? See entry 18, proven with a real SecurityDisabledException, and Security and Production.
  • Is Connect deployed standalone for anything that needs fault tolerance, rather than connect-distributed.sh? See the AI Bug Catalog, entry 19.
  • Does a connector config reference a class that is on plugin.path, not just present somewhere on disk? See entry 19, proven with a real ClassNotFoundException-shaped BadRequestException despite the jar existing.
  • Is errors.deadletterqueue.topic.name set together with errors.tolerance=all (real default: none) — and only on a sink connector? See entry 20, proven live against a running worker’s /config/validate.
  • Does code assume a KafkaJS consumer can join a share group (KIP-932) at all? See entry 21, proven with a real, empty grep of the client’s own type definitions, and Choosing a Processing Layer.
  • Is tsc --noEmit run over every TypeScript snippet before trusting it compiles — knowing it validates types, never durability, ordering, or commit semantics? See Verification Tools.
  • Is kafka-configs.sh --describe --all run against the real broker before trusting a config key exists and is dynamically alterable, rather than assumed from a tutorial? See Verification Tools.
  • Does CI run this course’s own harness (npm run verify, --run, --cli, --props) against every fence, not just a human skim? See Verification Tools.
Why does the 'Ops & security' group's coverage diagram say 'CLI/broker rejects outright' while 'Topic & broker config' says 'accepted, not rejected'?
Which checklist group covers reviewing this snippet, and what does catching it depend on?
const producer = kafka.producer({ transactionalId: 'payments-tx-1' });
await producer.connect();
await producer.send({ topic: 'accounts', messages: [{ value: 'debit' }] });
Why does the checklist ask specifically whether errors.tolerance=all is set together with errors.deadletterqueue.topic.name, rather than just 'is a DLQ topic name configured'?