# noUncheckedIndexedAccess enabled

- **Pattern:** `ab-002136` (`code-quality-essentials.type-safety.unchecked-indexed-access`)
- **Severity:** critical
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002136
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002136)

## Why it matters

`noUncheckedIndexedAccess` is not covered by the `strict` umbrella — it must be set explicitly, and most TypeScript projects never do. Without it, `array[0]` is typed as `T` even when the array is empty, so `array[0].name` compiles fine and throws `Cannot read properties of undefined` at runtime. ISO 25010:2011 §6.5.4 flags this as a reliability defect. This is one of the highest-signal, lowest-friction compiler flags available: it adds `| undefined` to every index access and forces you to handle the empty case.

## Severity rationale

Critical because every array index access in the codebase is a potential undefined crash that the compiler is actively hiding from you — one empty API response is enough to trigger it.

## Remediation

Add `"noUncheckedIndexedAccess": true` to your `tsconfig.json` `compilerOptions`. It is not implied by `strict: true`, so it must be explicit. The flag will surface every unguarded array access — fix them with optional chaining or an explicit undefined check.

```typescript
// Before (unsafe — crashes if items is empty):
const first = items[0].name;

// After (safe):
const first = items[0]?.name;
// or:
const item = items[0];
if (item !== undefined) { console.log(item.name); }
```

```json
{
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true
  }
}
```

## Detection

- **ID:** `unchecked-indexed-access`
- **Severity:** `critical`
- **What to look for:** In `tsconfig.json` `compilerOptions`, look for `"noUncheckedIndexedAccess": true`. This flag is not covered by the `strict` umbrella — it must be set explicitly. Without it, TypeScript treats `array[0]` as type `T` even when the array could be empty (it should be `T | undefined`). This is one of the most common sources of runtime `undefined` crashes in TypeScript codebases. Check that this option is set in the `tsconfig.json` that governs application source files (not just a test-specific config).
- **Pass criteria:** Enumerate all tsconfig files (root and workspace overrides). Quote the actual `noUncheckedIndexedAccess` value. `noUncheckedIndexedAccess: true` must be present in at least 100% of configs in the tsconfig covering application source files. On pass, report the count of tsconfig files verified.
- **Fail criteria:** The flag is absent or explicitly set to `false`. Having `strict: true` without explicitly adding `noUncheckedIndexedAccess` does not count as pass for this check.
- **Skip (N/A) when:** Project has no TypeScript files.
- **Detail on fail:** `"noUncheckedIndexedAccess not set in tsconfig.json; array/object index access returns T instead of T | undefined"`
- **Remediation:** Add the flag to `tsconfig.json`. It will surface places where you access array indices or record keys without checking for `undefined` first. Common patterns to fix:

  ```typescript
  // Before (unsafe):
  const first = items[0].name; // crashes if items is empty

  // After (safe):
  const first = items[0]?.name;
  // or
  const item = items[0];
  if (item !== undefined) {
    console.log(item.name);
  }
  ```

  ```json
  {
    "compilerOptions": {
      "strict": true,
      "noUncheckedIndexedAccess": true
    }
  }
  ```

## External references

- iso-25010 maintainability.modifiability

Taxons: code-quality

HTML version: https://auditbuffet.com/patterns/ab-002136
