• Sound mode S-13, pre-alpha
  • Design record 0007, Accepted

TSR1301

'{0}' can throw '{1}', which is not in its '@throws' tags. Catch it or add a '@throws' tag for it.

A function with '@throws' tags can throw something its tags don't list. Catch it, or add a '@throws' tag for it.

Rule S-13: Checked exceptions (level: sound). Reported by ts-r-check and ts-r-lsp in files that opt in to sound mode. See Sound mode.

What it means

In sound mode throwing is part of a function's signature. A function with @throws {T} JSDoc tags must not let anything escape that isn't assignable to the union of the tagged types. It's reported at the throw, or at the call it escapes from.

Example

Spec case from design record 0007 (checked by the record's case harness, not by this site's build)
// The function throws a type its tag doesn't list.
class NotFound extends Error {
  readonly code = "NOT_FOUND";
}
class Timeout extends Error {
  readonly code = "TIMEOUT";
}
/** @throws {NotFound} */
function find(id: string): string {
  if (id === "slow") throw new Timeout("slow"); // @expect TSR1301
  if (id === "") throw new NotFound("missing");
  return id;
}
export const v: string = find("a");

How to fix

  • Catch the exception inside the function.
  • Or add a tag for it: /** @throws {NotFound | Timeout} */.
  • For bugs that should never happen, use panic(message) from @ts-r.dev/guard, which is unchecked.

Sound mode is defined in design record 0007 (accepted 2026-10-15).