Inferensys

Prompt

Null Safety and Optional Handling Prompt

A practical prompt playbook for using the Null Safety and Optional Handling Prompt to detect unsafe null access patterns in pull request diffs.
Developer doing prompt engineering on laptop, prompt variations visible on screen, casual coding session.
PROMPT PLAYBOOK

When to Use This Prompt

Understand the ideal use cases, required inputs, and critical limitations of the null safety review prompt before integrating it into your workflow.

This prompt is designed for engineering teams that want to automate the detection of null pointer exceptions, improper optional unwrapping, and missing null guards in code changes. It reviews a pull request diff and produces a structured list of unsafe access patterns with fix suggestions. Use this prompt in CI/CD pipelines, pre-merge review checks, or as part of a developer's local workflow. It is most effective for languages with explicit nullability concerns such as Java, Kotlin, Swift, TypeScript (strict mode), C#, and Rust. The prompt assumes a unified diff format as input and does not execute code. It is a static analysis reasoning layer, not a replacement for a compiler or a human reviewer on critical paths.

The prompt requires a unified diff as the primary [INPUT]. For best results, provide additional [CONTEXT] such as the language version, nullability annotations used in the project (e.g., @NonNull, ?), and any team-specific conventions for optional handling. The expected [OUTPUT_SCHEMA] is a JSON array of findings, where each object includes the file path, line number, unsafe pattern description, severity (CRITICAL, HIGH, MEDIUM), and a concrete fix suggestion. You must validate that the output line numbers map to actual lines in the input diff; a hallucinated line reference is a common failure mode that should trigger a retry or human review. For high-risk codebases such as payment processing or safety-critical systems, always require a human to approve findings marked CRITICAL before merging.

Do not use this prompt for languages without nullability concepts, for runtime null analysis, or for diffs that exceed the model's context window without chunking. The prompt identifies patterns, not guaranteed exploits—it will miss null risks that depend on runtime state or cross-method invariants. Pair this prompt with a static analysis tool and treat its output as an additional review layer, not a sole gate. For production CI/CD integration, wrap the prompt in a harness that validates output schema, retries on malformed JSON, logs every finding with the commit SHA, and routes CRITICAL findings to a human approval queue before the merge can proceed.

PRACTICAL GUARDRAILS

Use Case Fit

Where the Null Safety and Optional Handling Prompt delivers reliable value and where it introduces unacceptable risk.

01

Good Fit: Languages with Explicit Nullability

Use when: the codebase uses Kotlin, Swift, TypeScript (strict mode), Rust, or C# with nullable reference types enabled. The prompt excels at tracing type-level nullability contracts through function signatures and call sites. Guardrail: always provide the language and null-safety mechanism in [CONTEXT] so the model applies the correct unwrapping idioms.

02

Bad Fit: Dynamic or Untyped Code

Avoid when: reviewing Python, JavaScript (non-strict), Ruby, or PHP diffs without type annotations. The model cannot reliably infer nullability intent from untyped variables and will produce high false-positive rates. Guardrail: require type hints, JSDoc annotations, or static analysis output as supplementary input before using this prompt.

03

Required Input: Diff Plus Type Context

Risk: without access to type definitions, the model guesses nullability from naming conventions or control flow, leading to missed unsafe accesses. Guardrail: include the diff alongside relevant type declaration files, interface definitions, or nullable annotations. The prompt harness should validate that type context is present before execution.

04

Operational Risk: False Sense of Safety

Risk: teams may treat the prompt output as exhaustive, skipping manual review of null safety in complex generic code, reflection, or serialization boundaries. Guardrail: position the prompt as a first-pass scanner, not a replacement for static analysis tools or human review. Flag any finding marked as high severity for mandatory human verification.

05

Boundary Risk: Interop and External Data

Risk: the prompt analyzes code patterns but cannot verify runtime nullability of data from APIs, databases, or user input where the type system guarantee breaks down. Guardrail: add a separate validation step for deserialization boundaries. The prompt harness should warn when the diff touches JSON parsing, database reads, or network responses without explicit null checks.

06

Variant: Pair with Static Analysis

Use when: you want higher recall on null safety issues. Run a static analysis tool first, then feed its findings alongside the diff into the prompt for contextual interpretation and false-positive filtering. Guardrail: the prompt should explain why each static analysis warning is or is not a real risk, not just repeat the tool output.

PROMPT PLAYBOOK

Copy-Ready Prompt Template

A reusable prompt template with square-bracket placeholders for reviewing a code diff for null safety and optional handling issues.

This section provides the core prompt for analyzing a pull request diff to identify potential null pointer exceptions, improper optional unwrapping, and missing null guards. The template is designed to be copied directly into your AI harness, CI/CD pipeline, or local development workflow. Replace the square-bracket placeholders with your specific diff content, target language, and output preferences before sending it to the model. The prompt is structured to produce a machine-readable JSON output, making it suitable for integration with code review tools and automated quality gates.

text
You are a senior software engineer specializing in null safety and defensive programming. Your task is to review the provided code diff for potential null pointer exceptions, improper optional unwrapping, and missing null guards.

## INPUT
[DIFF]

## LANGUAGE CONTEXT
[LANGUAGE] (e.g., Java, Kotlin, Swift, TypeScript, Python with type hints)

## OUTPUT SCHEMA
Return a JSON object with the following structure:
{
  "findings": [
    {
      "file": "string (relative file path)",
      "line": "number (the line in the new file where the issue occurs)",
      "severity": "HIGH | MEDIUM | LOW",
      "category": "NULL_DEREFERENCE | UNSAFE_UNWRAP | MISSING_GUARD | REDUNDANT_CHECK | INCONSISTENT_NULLABILITY",
      "description": "string (clear explanation of the risk)",
      "suggestion": "string (concrete fix, including code pattern or language-specific idiom)",
      "context_snippet": "string (the relevant 2-3 lines from the diff)"
    }
  ],
  "summary": {
    "total_findings": "number",
    "high_severity": "number",
    "medium_severity": "number",
    "low_severity": "number",
    "risk_assessment": "SAFE | CAUTION | UNSAFE"
  }
}

## CONSTRAINTS
- Only report findings that are introduced or affected by the diff. Do not flag pre-existing issues in unchanged code unless the diff makes them reachable.
- For [LANGUAGE], use language-specific idioms: Optional chaining (?.) and nullish coalescing (??) for JavaScript/TypeScript; `Optional.ofNullable` or `@Nullable` annotations for Java; `if let`, `guard let`, or nil-coalescing for Swift; safe call (?.) and Elvis (?:) for Kotlin.
- If the diff adds a public API, flag any parameter or return type that is nullable without documentation.
- If a finding is a false positive due to a framework guarantee or an invariant enforced elsewhere, do not include it.
- Do not suggest removing null checks unless they are provably redundant and the removal does not introduce risk.

## EXAMPLES
Input diff line: `String name = user.getName();` followed by `name.toLowerCase();`
Output finding: HIGH severity, NULL_DEREFERENCE, "user.getName() may return null, but the result is dereferenced without a null check on the next line."

Input diff line: `val value = optional.get()` without a preceding `isPresent()` check.
Output finding: HIGH severity, UNSAFE_UNWRAP, "Calling optional.get() without checking isPresent() will throw NoSuchElementException if the Optional is empty."

## RISK_LEVEL
[RISK_LEVEL] (e.g., CRITICAL_PATH, STANDARD, LOW_RISK) - If CRITICAL_PATH, flag even LOW severity findings and require explicit nullability annotations on all new public methods.

To adapt this template for your workflow, replace the [DIFF] placeholder with the actual unified diff output from your version control system. Set [LANGUAGE] to the primary language of the codebase, as this controls the idioms suggested in fix recommendations. The [RISK_LEVEL] parameter adjusts the strictness of the review: use CRITICAL_PATH for authentication, payment, or data integrity code where any null dereference is unacceptable; use STANDARD for general application code; use LOW_RISK for internal tooling or scripts where a failure is tolerable. The output JSON is designed to be parsed by a validation harness that can check line numbers against the actual diff, verify that context snippets match the referenced code, and route HIGH severity findings for mandatory human review before merge.

IMPLEMENTATION TABLE

Prompt Variables

Required and optional inputs for the Null Safety and Optional Handling Prompt. Wire these placeholders into your CI/CD pipeline or code review harness before sending the prompt.

PlaceholderPurposeExampleValidation Notes

[DIFF]

The unified diff or patch file to review for null safety and optional handling issues

git diff main...feature-branch > review.diff

Must be non-empty plain text. Validate with wc -l > 0. Reject binary diffs or non-unified formats.

[LANGUAGE]

Target programming language to scope nullability rules and idioms

kotlin

Must match a supported language key: java, kotlin, swift, typescript, csharp, dart, rust, python. Validate against allowlist before prompt assembly.

[NULLABLE_ANNOTATIONS]

List of nullability annotations or keywords the codebase uses to mark nullable and non-null types

@Nullable, @NonNull, ?, !!, Optional<T>, ?.

Provide as comma-separated string. If empty or null, prompt defaults to language-standard annotations. Validate that annotations match [LANGUAGE] conventions.

[FRAMEWORK_CONTEXT]

Optional framework or library context that affects null handling patterns

Spring Boot, Android SDK, React

Can be null. When provided, helps the prompt recognize framework-specific null idioms like lateinit in Android or @Autowired injection. No strict validation required.

[SEVERITY_THRESHOLD]

Minimum severity level to include in output

medium

Must be one of: low, medium, high, critical. Defaults to medium if null. Validate enum membership. Findings below threshold are excluded from output.

[MAX_FINDINGS]

Maximum number of findings to return in the output

15

Must be a positive integer between 1 and 50. Defaults to 20 if null. Validate range. Prompt truncates output to this limit, prioritizing highest severity first.

[OUTPUT_SCHEMA]

Expected JSON schema for structured review output

{"findings": [{"file": "string", "line": "int", "severity": "string", "pattern": "string", "suggestion": "string"}]}

Must be a valid JSON Schema object or null. When null, prompt uses default schema. Validate with JSON Schema parser before injection. Schema must include file, line, severity, pattern, and suggestion fields at minimum.

PROMPT PLAYBOOK

Implementation Harness Notes

How to wire the null safety prompt into a CI/CD pipeline or local pre-commit hook with validation, retries, and human review gates.

The null safety prompt is designed to be called programmatically as part of a PR review workflow. It expects a raw diff as input and returns a structured JSON payload of findings. The implementation harness should treat this prompt as a deterministic analysis step: same diff, same model, same temperature (0) should produce consistent results. Wire it into your CI pipeline as a non-blocking check for non-critical paths, or as a blocking check with a human override for repositories where null safety is a hard gate. For local use, integrate it into a pre-commit hook that runs the prompt against staged changes and surfaces findings before the commit is finalized.

The harness must validate the model's output against a strict JSON schema before accepting it. Each finding object requires file, line, severity, pattern, and suggestion fields. If the model returns malformed JSON or missing required fields, retry once with a repair prompt that includes the raw output and the schema. If the retry also fails, log the failure and fall back to a human review flag. For high-risk repositories (e.g., payment processing, safety-critical systems), route all critical severity findings to a human approval queue before the PR can merge. Use a model with strong code understanding and JSON mode support—Claude 3.5 Sonnet or GPT-4o are good defaults. Avoid smaller or older models that may hallucinate line numbers or miss language-specific null patterns like Swift's force-unwrap or Kotlin's !! operator.

Log every prompt invocation with the diff hash, model version, findings count, and validation status. This creates an audit trail for debugging false positives and tracking prompt drift over time. For evaluation, maintain a golden dataset of diffs with known null safety issues and run the prompt against it on every prompt change. Measure precision (are flagged lines actually unsafe?) and recall (did it miss known issues?). If false positive rates exceed 15% on your golden set, tune the prompt's [CONSTRAINTS] or add few-shot examples of safe patterns that the model is over-flagging. Do not ship a prompt update without running it against your eval set first.

IMPLEMENTATION TABLE

Expected Output Contract

Schema contract for the null safety review output. Use this to validate the model response before ingesting it into a CI/CD pipeline or review dashboard.

Field or ElementType or FormatRequiredValidation Rule

findings

Array of objects

Must be a JSON array. If no issues found, return an empty array [].

findings[].id

String (kebab-case)

Must match pattern ^finding-[a-z0-9-]+$. Must be unique within the array.

findings[].severity

Enum: critical, high, medium, low

Must be one of the allowed enum values. critical requires immediate human approval.

findings[].file_path

String (relative path)

Must be a non-empty string matching a file path present in the provided [DIFF_CONTEXT].

findings[].line_number

Integer or null

If the issue maps to a specific line, provide the new line number from the diff. If the issue is structural (e.g., missing guard across a file), set to null.

findings[].unsafe_pattern

String

A concise description of the unsafe access pattern (e.g., 'Direct optional unwrap without nil check'). Must not be empty.

findings[].fix_suggestion

String

A concrete, actionable suggestion (e.g., 'Use guard let or if let to safely unwrap'). Must not be empty.

findings[].confidence

Number (0.0 to 1.0)

Model's confidence in the finding. Findings with confidence < 0.7 should be flagged for human review in the UI but still included.

PRACTICAL GUARDRAILS

Common Failure Modes

What breaks first when reviewing diffs for null safety and how to guard against it.

01

False Positives on Guarded Access

What to watch: The model flags a variable as unsafe even though a preceding if (x != null) or an assertion already guards it. This happens when the model fails to track control flow across the full diff context. Guardrail: Always include the complete function or method in the diff context, not just the changed lines. Validate flagged findings against a static analysis tool to filter out already-guarded access.

02

Missed Nulls from External Sources

What to watch: The model overlooks values returned from API calls, database queries, or map lookups that can return null. It focuses on local variable assignments but misses the nullability contract of external functions. Guardrail: Provide the function signatures or API schemas for any external calls in the diff. Add a specific instruction to check return values from all external interfaces.

03

Language-Specific Null Semantics Confusion

What to watch: The model applies the wrong null-handling rules for the language in use—for example, treating JavaScript's null and undefined as identical, or confusing Kotlin's platform types with nullable types. Guardrail: Explicitly state the target language and its nullability model in the system prompt. Include a language-specific cheat sheet for null behavior as part of the prompt context.

04

Optional Chaining Over-Recommendation

What to watch: The model suggests wrapping every access in optional chaining (?.) or safe calls without considering whether a null at that point indicates a bug that should fail fast. This masks real logic errors. Guardrail: Instruct the model to distinguish between expected nulls (use safe access) and invariant violations (use assertions or explicit throws). Add a severity field to each finding to separate style suggestions from crash risks.

05

Context Window Truncation on Large Diffs

What to watch: For large PRs, the diff exceeds the context window, and the model reviews only the first portion. Null safety issues in truncated sections are silently missed. Guardrail: Chunk the diff by file or function before review. Run the prompt on each chunk independently and merge results. Add a completeness check that verifies every changed file appears in the output.

06

Inconsistent Severity Grading

What to watch: The same null-safety pattern is flagged as critical in one file and low-severity in another, or the model fails to distinguish between a null that crashes production and a null that causes a minor log warning. Guardrail: Provide a clear severity rubric in the prompt with concrete examples: Critical (crashes or data loss), High (user-facing error), Medium (degraded feature), Low (cosmetic). Use few-shot examples to calibrate grading.

IMPLEMENTATION TABLE

Evaluation Rubric

Criteria for evaluating the null safety review prompt's output before integrating it into a CI/CD pipeline. Each criterion maps to a pass standard, a failure signal, and a concrete test method.

CriterionPass StandardFailure SignalTest Method

Schema Compliance

Output is valid JSON matching the defined [OUTPUT_SCHEMA] with all required fields present

JSON parse error or missing required fields like 'file_path' or 'severity'

Automated schema validation against the contract using a JSON Schema validator

Finding Completeness

All unsafe null access patterns in the [INPUT_DIFF] are identified with no false negatives against a known set of seeded vulnerabilities

A known unsafe pattern (e.g., direct .get() without check) is present in the diff but missing from the output

Run prompt against a golden diff containing 5-10 known null safety issues and compare output list to the expected set

False Positive Rate

Zero false positives where a safe null-handling pattern is incorrectly flagged as a risk

A finding points to a line where null is already guarded by an if (x != null) check or an Optional.isPresent() call

Manual review of a sample of 50 findings or automated check against a labeled dataset of safe/unsafe patterns

Severity Accuracy

Severity levels (e.g., 'critical', 'high', 'medium') correctly reflect the runtime impact: unguarded dereference is 'critical', missing Optional check is 'high'

A cosmetic null check suggestion is labeled 'critical' or a guaranteed NPE is labeled 'low'

Spot-check 10 findings against a predefined severity rubric; require 90% agreement with a senior developer's rating

Line Number Precision

Each finding's line reference maps exactly to the line in the [INPUT_DIFF] where the unsafe access occurs

A finding references a line number that contains a comment, whitespace, or unrelated code

Parse the diff to extract line numbers and verify each finding's line reference exists and contains a potential null access

Fix Suggestion Relevance

Each finding includes a concrete, compilable code suggestion that resolves the null risk without altering intended logic

Suggestion is generic ('add null check'), introduces a new bug, or does not compile in the target language

Automated check that suggestion text contains a code block; manual review of 5 suggestions for compilability and correctness

Language-Specific Pattern Recognition

Correctly identifies null-safety patterns for the language in [LANGUAGE_CONTEXT] (e.g., ?. in Kotlin, Optional in Java, None checks in Python)

Flags a language-idiomatic safe pattern as a risk or misses a language-specific unsafe pattern

Test with diffs in 3 different languages; require >80% accuracy in distinguishing safe vs unsafe idioms per language

Output Determinism

Running the same prompt with the same [INPUT_DIFF] and [CONSTRAINTS] twice produces an identical set of findings with the same severity and line numbers

Two runs produce different counts of findings or different severity assignments for the same code block

Execute the prompt twice with temperature=0 and compare the JSON outputs using a deep equality check

ADAPTATION OPTIONS

Adapt This Prompt

How to adapt

Use the base prompt with a lightweight output schema. Focus on getting a list of unsafe access patterns without requiring line-number precision or severity scoring. Accept plain text or simple JSON arrays.

code
Analyze this diff for null safety issues. For each unsafe access, output:
- File and approximate location
- The unsafe pattern (e.g., unchecked optional unwrap, missing null guard)
- A one-line fix suggestion

[DIFF]

Watch for

  • Missing schema checks leading to inconsistent output shapes
  • Overly broad instructions that flag defensive null checks as issues
  • Model hallucinating line numbers that don't exist in the diff
Prasad Kumkar

About the author

Prasad Kumkar

CEO & MD, Inference Systems

Prasad Kumkar is the CEO & MD of Inference Systems and writes about AI systems architecture, LLM infrastructure, model serving, evaluation, and production deployment. Over 5+ years, he has worked across computer vision models, L5 autonomous vehicle systems, and LLM research, with a focus on taking complex AI ideas into real-world engineering systems.

His work and writing cover AI systems, large language models, AI agents, multimodal systems, autonomous systems, inference optimization, RAG, evaluation, and production AI engineering.