When a field typed as string returns null at runtime, consumers get a type error or a silent coercion depending on their language. When some endpoints omit missing fields and others include them as null, every consumer must guard against both undefined and null for every optional field. This is the most common source of unexpected Cannot read properties of null errors in client applications. iso-25010:2011 compatibility.interoperability requires that the schema truthfully represent what the API sends — nullability is a core part of that contract.
Medium because undeclared nullability causes runtime type errors in consumers and forces defensive null-guarding throughout client code without enabling direct security exploits.
Mark nullable fields explicitly in both your TypeScript types and your OpenAPI schema. Choose one approach for missing data — always include with null, or always omit — and document it:
// TypeScript -- explicit nullability:
interface UserResponse {
id: string // always present
name: string // always present
avatarUrl: string | null // explicitly nullable
bio: string | null // explicitly nullable
}
# OpenAPI -- nullable fields:
UserResponse:
type: object
required: [id, name]
properties:
avatarUrl: { type: string, nullable: true }
Consistency between "return null" and "omit the field" is non-negotiable — consumers cannot handle both reliably.
ID: api-design.contract-quality.nullable-explicit
Severity: medium
What to look for: Examine response objects for fields that can be null. Check whether nullability is explicitly documented in the schema (OpenAPI nullable: true or union type with null, GraphQL non-null ! vs nullable, TypeScript | null annotations, Pydantic Optional types). Look for fields that sometimes return a value and sometimes return null or are absent entirely -- consumers need to know which fields are reliably present. Also check: does the API return null for missing fields, or omit them entirely? Consistency matters.
Pass criteria: Count all fields that can return null across response types. Nullable fields are explicitly marked in the schema or type definitions. The API consistently either returns null for empty optional fields or omits them (one approach, not both). Consumers can determine from the schema which fields may be null. At least 90% of nullable fields must have explicit nullability annotations.
Fail criteria: Fields that can be null are not marked as nullable in the schema or types. The API inconsistently returns null for some missing fields and omits others. Consumers discover nullability through runtime errors.
Skip (N/A) when: No schema or type definitions exist (covered by other checks). Also skip if all response fields are always non-null by design.
Detail on fail: Identify the ambiguity (e.g., "User.avatarUrl is typed as string but returns null when no avatar is set. Order.shippedAt is sometimes absent from the response and sometimes null. Schema does not mark either field as nullable."). Max 500 chars.
Remediation: Make nullability explicit in your schema and types:
// TypeScript -- explicit nullability:
interface UserResponse {
id: string // always present
name: string // always present
avatarUrl: string | null // explicitly nullable
bio: string | null // explicitly nullable
}
# OpenAPI -- nullable fields:
UserResponse:
type: object
required: [id, name]
properties:
id: { type: string }
name: { type: string }
avatarUrl: { type: string, nullable: true }
Choose one approach for missing data: always include the field with null, or always omit it. Document which approach you use.