This prompt is a static analysis tool for Go engineers and CI/CD pipelines that must detect deadlock risks in goroutine communication patterns before code merges. It is designed to analyze the structure of channel operations and select statements within a provided source file or function, identifying unbuffered channel mismatches, missing default cases that cause goroutine starvation, and select constructs where no case can proceed. The primary job-to-be-done is to produce a communication graph and a trace of potential deadlock scenarios, turning a manual, error-prone review into a structured, repeatable analysis. The ideal user is a senior Go engineer or a platform team automating pre-merge safety checks, not a developer debugging a live production incident.
Prompt
Channel and Select Statement Deadlock Prompt

When to Use This Prompt
Defines the ideal use case, required inputs, and boundaries for the channel and select statement deadlock analysis prompt.
To use this prompt effectively, you must provide the full source code of the functions or files containing the concurrency logic. The prompt assumes the code compiles and focuses exclusively on chan and select semantics; it will not catch lock-based deadlocks, race conditions on shared memory, or runtime goroutine leaks. The required input is a complete, self-contained code block. The expected output is a structured report that includes a list of identified communication pairs, a directed graph of channel dependencies, and a trace of events that would lead to a deadlock. You should wire this into a CI pipeline by running it on the diff of a pull request, validating that the output schema contains deadlock_detected and trace fields, and failing the check only if a high-severity deadlock is found with a complete, reproducible trace.
Do not use this prompt for analyzing runtime traces, pprof goroutine dumps, or code written in languages other than Go. It is not a substitute for the Go race detector or for stress-testing with go test -race. The prompt is a pre-merge guardrail, and its findings should be reviewed by a human for complex or novel concurrency patterns. If the analysis returns a deadlock trace, treat it as a high-priority finding that requires a code change or a documented justification for why the static analysis is a false positive. For production debugging, pair this with runtime tooling, not a static prompt.
Use Case Fit
Where the Channel and Select Statement Deadlock Prompt delivers reliable pre-merge detection and where it introduces noise or false confidence.
Good Fit: Pre-Merge Go Code Review
Use when: A pull request introduces new channel operations, select statements, or goroutine spawning logic. The prompt excels at static analysis of communication graphs before runtime. Guardrail: Always pair the prompt's output with a checklist item requiring the author to trace one full send/receive lifecycle for each unbuffered channel.
Good Fit: Refactoring Legacy Synchronization
Use when: Replacing mutex-based synchronization with channels or restructuring select statements for readability. The prompt catches ordering regressions introduced during cleanup. Guardrail: Provide the full diff context including the old synchronization code so the model can compare communication patterns, not just review the new code in isolation.
Bad Fit: Runtime Deadlock Diagnosis
Avoid when: You have a goroutine dump from a running system and need to identify which goroutine holds which lock. This prompt analyzes source code statically; it cannot parse runtime stack traces. Guardrail: Route runtime deadlock incidents to a log analysis prompt or a dedicated debugging tool like pprof before attempting source-level review.
Bad Fit: Dynamic Channel Creation
Avoid when: Channels are created in loops, stored in slices, or selected via reflection based on runtime configuration. The static analysis approach cannot reason about channel counts unknown at compile time. Guardrail: Flag any code containing reflect.Select or dynamic make(chan...) in loops and escalate to a senior reviewer for manual interleaving analysis.
Required Inputs
Risk: Incomplete input produces false negatives. The prompt needs the full select statement block, all channel declarations (buffered/unbuffered status), and the goroutine spawning context. Guardrail: Build a pre-processing step that extracts channel declarations and select blocks from the diff before calling the prompt. Reject the analysis if no channel declarations are found.
Operational Risk: False Confidence in Clean Reports
Risk: A 'no deadlock found' result may be misinterpreted as a guarantee of safety, especially when the analysis missed context-dependent paths. Guardrail: Always append a disclaimer to the output: 'This static analysis cannot guarantee absence of deadlocks under all interleavings. Concurrent stress testing is required for critical paths.' Never gate a production deployment solely on this prompt's output.
Copy-Ready Prompt Template
A reusable prompt template for detecting deadlock scenarios in Go channel operations and select statements, ready to copy and adapt.
This prompt template is designed to analyze Go source code containing channel operations and select statements for potential deadlock scenarios. It accepts raw code, optional runtime traces, and configuration parameters to produce a structured deadlock analysis. The template uses square-bracket placeholders that you replace with actual values before sending the prompt to the model. Each placeholder maps to a specific input source in your application: code snippets come from PR diffs or repository files, runtime traces come from your observability pipeline, and constraints come from your team's review policies.
textYou are a concurrency safety reviewer specializing in Go channel deadlock detection. Analyze the following Go code for deadlock risks in channel operations and select statements. ## INPUT ### Code to Review [CODE_SNIPPET] ### Runtime Trace (optional) [GOROUTINE_TRACE] ### Additional Context - Package: [PACKAGE_NAME] - Function(s) under review: [FUNCTION_NAMES] - Known goroutine count: [GOROUTINE_COUNT] ## CONSTRAINTS [CONSTRAINTS] ## OUTPUT SCHEMA Return a JSON object with this exact structure: { "findings": [ { "id": "string", "severity": "DEADLOCK | STARVATION | LEAK | WARNING", "location": { "file": "string", "line_start": number, "line_end": number }, "pattern": "UNBUFFERED_CHANNEL_MISMATCH | MISSING_DEFAULT_CASE | SELECT_STARVATION | BLOCKING_SEND_NO_RECEIVER | BLOCKING_RECEIVE_NO_SENDER | CLOSED_CHANNEL_SEND | NIL_CHANNEL_OPERATION | CIRCULAR_WAIT", "description": "string explaining the deadlock mechanism", "reproduction_scenario": "string describing how to trigger the deadlock", "fix_suggestion": "string with concrete code change recommendation", "communication_graph": { "nodes": ["string goroutine or channel names"], "edges": [{"from": "string", "to": "string", "operation": "SEND | RECEIVE", "blocking": true}] } } ], "deadlock_trace": "string describing the circular wait chain if a deadlock exists", "overall_risk": "HIGH | MEDIUM | LOW | NONE", "summary": "string one-paragraph assessment" } ## ANALYSIS RULES 1. For each select statement, check if a default case exists and whether it prevents indefinite blocking. 2. Trace every channel send to its corresponding receive and vice versa. Flag unmatched operations. 3. Identify circular dependencies where goroutine A waits on B, B waits on C, and C waits on A. 4. Check for sends on unbuffered channels without a concurrent receiver goroutine. 5. Flag goroutines that block on channel operations without a cancellation path (context.Context or done channel). 6. If a runtime trace is provided, correlate static findings with observed goroutine states. 7. Do not flag patterns protected by explicit synchronization that you can verify in the code. 8. If the code is incomplete or the analysis is uncertain, set overall_risk to the worst-case scenario and note the uncertainty in summary.
To adapt this template, replace each placeholder with concrete values from your review pipeline. For [CODE_SNIPPET], provide the complete function or file content, not just the diff, because deadlock analysis requires seeing all channel interactions in scope. For [CONSTRAINTS], specify rules like "ignore test files" or "only flag findings with severity DEADLOCK or STARVATION" to control output volume. The [GOROUTINE_TRACE] placeholder accepts the output of runtime.Stack([]byte, true) or equivalent goroutine dump data, which dramatically improves detection accuracy when available. If you don't have a trace, replace the placeholder with "No runtime trace available" and the model will rely solely on static analysis. Before deploying this prompt, validate the output against known deadlock examples from your codebase and tune the ANALYSIS RULES section if the model produces false positives for patterns your team considers safe.
Prompt Variables
Required inputs for the Channel and Select Statement Deadlock Prompt. Each placeholder must be populated with concrete code, configuration, or analysis parameters before execution. Missing or malformed inputs will degrade deadlock detection accuracy.
| Placeholder | Purpose | Example | Validation Notes |
|---|---|---|---|
[CODE_SNIPPET] | Go source code containing channel operations and select statements to analyze for deadlock potential | func main() { ch := make(chan int); ch <- 1 } | Must be valid Go syntax. Parse check with go/parser before prompt execution. Empty snippets return null analysis. |
[ANALYSIS_DEPTH] | Controls how exhaustively the prompt explores interleaving paths and starvation scenarios | exhaustive | Must be one of: quick, standard, exhaustive. Quick skips starvation analysis. Invalid values default to standard with a warning. |
[CONTEXT_FILES] | Additional source files defining channel types, wrapper functions, or synchronization helpers referenced by the snippet | []string{"pkg/worker/pool.go", "pkg/worker/queue.go"} | Optional. Each path must resolve to a readable file. Missing files are skipped with a note in output. Null allowed. |
[BUFFER_CONFIG] | Explicit buffer sizes for channels when not inferrable from the snippet alone | map[string]int{"results": 10, "errors": 0} | Optional. Keys must match channel variable names in snippet. Size 0 indicates unbuffered. Null allowed when all buffer sizes are inline. |
[GOROUTINE_COUNT] | Expected or maximum number of concurrent goroutines interacting with the channels | 5 | Optional integer. Used to validate send/receive pair counts. Null allowed when count is dynamic or unknown. |
[SELECT_TIMEOUTS] | Whether select statements include timeout or default cases, when not visible in the snippet | Optional boolean. Set true if time.After or default cases exist outside the snippet. Null allowed when all select cases are visible in [CODE_SNIPPET]. | |
[OUTPUT_FORMAT] | Desired structure for the deadlock analysis output | communication_graph | Must be one of: communication_graph, deadlock_trace, full_report. Controls whether output emphasizes graph visualization, execution traces, or comprehensive analysis. |
Implementation Harness Notes
How to wire the Channel and Select Statement Deadlock Prompt into a CI/CD pipeline or interactive review tool with validation, retries, and structured output parsing.
This prompt is designed to be called programmatically as part of a pre-merge code review pipeline or an interactive CLI tool for Go developers. The primary integration point is a diff ingestion service that extracts only Go source files containing chan, select, go func, or sync primitives, packages them with a lightweight static analysis summary, and sends the assembled [CONTEXT] to the model. Because deadlock analysis is computationally expensive for LLMs on large codebases, you should pre-filter diffs to include only the changed functions plus any directly called functions (call graph depth of 1) to stay within context windows and manage latency. The model should receive the code, a list of channel declarations with their buffer sizes and directions, and any existing go vet or staticcheck findings related to concurrency.
Validation and output parsing: The prompt instructs the model to return a JSON array of deadlock findings. Your harness must validate this output against a strict schema before accepting it. Each finding object requires severity (one of CRITICAL, HIGH, MEDIUM, LOW), file_path, line_range, deadlock_type (one of unbuffered_channel_mismatch, select_starvation, missing_default_case, goroutine_leak, circular_wait), description, and fix_suggestion. Use a JSON Schema validator in your pipeline to reject malformed responses and trigger a retry. For retries, append the validation error message to the next request as [PREVIOUS_VALIDATION_ERROR] so the model can self-correct. Set a maximum of 2 retries before falling back to a human review flag. Model choice: Use a model with strong code reasoning capabilities (e.g., Claude 3.5 Sonnet, GPT-4o) and set temperature=0.1 for deterministic output. For cost-sensitive pipelines, route MEDIUM and LOW severity findings to a smaller model for initial triage and escalate only CRITICAL and HIGH to the primary model.
Logging and observability: Log every invocation with the commit SHA, file paths analyzed, number of findings returned, retry count, and model latency. Store the raw model response and the validated output in your review database for auditability. If the model returns a deadlock_graph field (a Mermaid.js diagram of channel dependencies), render it in your review UI but do not block the pipeline on its presence—it is a supplementary artifact. Human review integration: Findings with severity: CRITICAL should block merge and require a human reviewer to acknowledge or dismiss each finding. Findings with severity: HIGH should generate a non-blocking comment on the PR with the fix_suggestion included. MEDIUM and LOW findings can be aggregated into a summary comment. What to avoid: Do not run this prompt on every commit unconditionally—use file extension and keyword filters to trigger it only when concurrency-relevant code changes. Do not trust the model's line numbers without verifying them against the current diff; line numbers can drift if the model references the full file rather than the diff hunk. Always include a [CONSTRAINTS] block that reminds the model to only report findings with high confidence and to explicitly state when no deadlock risks are detected rather than returning an empty array silently.
Expected Output Contract
Defines the required fields, types, and validation rules for the structured JSON output produced by the Channel and Select Statement Deadlock Prompt. Use this contract to parse and validate the model's response before integrating it into a CI/CD pipeline or review dashboard.
| Field or Element | Type or Format | Required | Validation Rule |
|---|---|---|---|
deadlock_analysis | object | Top-level object must exist and be parseable as JSON. | |
deadlock_analysis.summary | string | Must be a non-empty string. Check length > 10 characters. | |
deadlock_analysis.risk_level | string | Must be one of the enum: ['high', 'medium', 'low', 'none']. Case-sensitive check. | |
deadlock_analysis.communication_graph | array of objects | Must be a valid array. Each element must contain 'source' (string), 'target' (string), and 'operation' (string: 'send' or 'receive') fields. | |
deadlock_analysis.deadlock_traces | array of objects | Must be an array. If risk_level is 'none', array must be empty. Each trace object must have 'cycle' (array of strings) and 'description' (string). | |
deadlock_analysis.findings | array of objects | Must be an array. Each finding object must have 'location' (string, e.g., 'file:line'), 'severity' (string: 'critical', 'warning', 'info'), and 'recommendation' (string). | |
deadlock_analysis.select_starvation_risks | array of objects | If present, each object must have 'select_block' (string location) and 'missing_default_case' (boolean). Validate boolean type. | |
deadlock_analysis.unbuffered_channel_mismatches | array of objects | If present, each object must have 'channel_name' (string), 'send_location' (string), and 'receive_location' (string). All strings must be non-empty. |
Common Failure Modes
Channel and select statement deadlock analysis is brittle. These are the most common failure modes when using LLMs to detect concurrency bugs, and how to prevent them in your review pipeline.
False Positives on Intended Blocking
What to watch: The model flags a deliberate blocking channel operation (e.g., a server's main accept loop or a worker waiting on a task queue) as a deadlock risk. This happens when the prompt lacks context about the goroutine's lifecycle role. Guardrail: Require the prompt to classify each goroutine's termination condition before analyzing its channel operations. Include a 'deliberate blocking' category in the output schema and validate that long-lived server goroutines are not flagged.
Missed Deadlocks from Context Propagation Failures
What to watch: The model fails to detect a deadlock caused by a goroutine leaking because its parent context was cancelled, but a child goroutine is still blocked on a channel send with no receiver. The model often misses the connection between context cancellation and channel unblocking. Guardrail: Explicitly instruct the prompt to trace context propagation paths and check whether every channel operation has a cancellation path. Add a test case with a context-cancelled goroutine that blocks indefinitely on a send.
Select Starvation Misdiagnosis
What to watch: A select statement with a busy default case or a fast-firing channel starves other cases, but the model reports it as a deadlock rather than starvation. The distinction matters because the fix is different (fairness vs. unblocking). Guardrail: Include a severity classification in the output that separates deadlock (no progress possible) from starvation (progress possible but unfair). Validate that select statements with default cases are analyzed for starvation, not just deadlock.
Unbuffered Channel Mismatch Over-Reporting
What to watch: The model flags every unbuffered channel send without a visible receive at the same scope as a deadlock, ignoring that the receive happens in a goroutine spawned earlier or in a different file. This generates noise that causes reviewers to ignore real findings. Guardrail: Require the prompt to perform cross-goroutine and cross-file matching of send/receive pairs. If a matching receive exists in any reachable goroutine, the finding should be downgraded or suppressed. Validate with multi-file test cases.
Channel Close and Range Loop Blindness
What to watch: The model misses deadlocks where a goroutine ranges over a channel that is never closed, or where a channel is closed while another goroutine is still sending. These patterns are common in pipeline stages but often invisible to basic send/receive analysis. Guardrail: Add explicit checks for channel lifecycle: which goroutine is responsible for closing each channel, whether all senders have exited before close, and whether all receivers handle the closed channel case. Include a channel lifecycle summary in the output.
Buffered Channel Capacity Confusion
What to watch: The model treats a buffered channel as unbuffered or ignores capacity when analyzing whether a send will block. A buffered channel with available capacity won't deadlock, but the model may still flag it if it doesn't account for buffer state. Guardrail: Require the prompt to extract and track buffer capacity for every channel. When analyzing send operations, check remaining capacity before flagging a potential block. Include buffer capacity in the communication graph output.
Evaluation Rubric
Use this rubric to test the Channel and Select Statement Deadlock Prompt before integrating it into a CI pipeline or code review harness. Each criterion targets a specific failure mode common in concurrency analysis prompts.
| Criterion | Pass Standard | Failure Signal | Test Method |
|---|---|---|---|
Deadlock Cycle Detection | Prompt identifies all circular wait conditions in the provided [GO_SOURCE] snippet involving channels and select statements. | Output misses a known deadlock cycle present in the test fixture or reports a cycle that does not exist. | Run against a golden set of 10 Go snippets with pre-annotated deadlock graphs. Require 100% recall on true cycles and 0 false positives. |
Select Statement Starvation | Prompt correctly flags select cases that can never execute because a preceding case always succeeds immediately. | Output claims all cases are reachable when a starvation case exists, or flags a reachable case as starved. | Test with a snippet containing a |
Unbuffered Channel Mismatch | Prompt detects when a send on an unbuffered channel has no corresponding receive in any concurrent goroutine path. | Output classifies the channel operation as safe or fails to trace the goroutine that should be receiving. | Provide a snippet with a goroutine that sends on an unbuffered channel and exits before a receive is launched. Check for a deadlock trace in the output. |
Communication Graph Accuracy | The generated communication graph correctly maps all channel operations to their owning goroutines and shows send/receive pairs. | Graph contains an edge between goroutines that do not communicate, or omits a documented channel operation. | Parse the output graph structure and compare against a pre-computed adjacency matrix. Require exact node and edge match. |
False Positive Rate | Prompt does not flag safe, idiomatic patterns (e.g., a buffered channel used as a semaphore) as deadlocks. | Output issues a high-severity deadlock warning for a pattern known to be safe in the Go memory model. | Run against a negative test set of 15 safe concurrency patterns. Require a false positive rate below 5%. |
Severity Classification | Prompt assigns a severity of 'BLOCKER', 'HIGH', or 'LOW' that matches the ground-truth label based on production impact. | A guaranteed deadlock on startup is labeled 'LOW', or a theoretical-only race is labeled 'BLOCKER'. | Validate severity labels against a labeled dataset of 20 findings reviewed by a senior systems engineer. Require exact match on BLOCKER findings. |
Fix Suggestion Relevance | When [INCLUDE_FIX] is true, the suggested fix addresses the root cause without introducing a new concurrency bug. | Fix suggestion introduces a data race, removes necessary synchronization, or is syntactically invalid Go. | Apply the suggested fix to the test fixture and run |
Output Schema Compliance | Output is valid JSON matching the [OUTPUT_SCHEMA] exactly, with all required fields present and correctly typed. | Output is missing the | Validate output with a JSON Schema validator. Require zero schema violations across 50 test runs with varied inputs. |
Enabling Efficiency, Speed & Accuracy
Intelligent Analysis, Decision & Execution
We build AI systems for teams that need search across company data, workflow automation across tools, or AI features inside products and internal software.
Talk to Us
Search across company data
Give teams answers from docs, tickets, runbooks, and product data with sources and permissions.
Useful when people spend too long searching or get different answers from different systems.

Automate internal workflows
Use AI to route work, draft outputs, trigger actions, and keep approvals and logs in place.
Useful when repetitive work moves across multiple tools and teams.

Add AI to products and internal tools
Build assistants, guided actions, or decision support into the software your team or customers already use.
Useful when AI needs to be part of the product, not a separate tool.
Adapt This Prompt
How to adapt\nUse the base prompt with a single code snippet and lighter validation. Drop the communication graph requirement and ask for a plain-text deadlock trace instead. Accept a simpler output schema with just `findings` and `severity`.\n\n### Watch for\n- False positives on buffered channels that are correctly sized\n- Missed deadlocks when the snippet omits the full goroutine lifecycle\n- Overly broad instructions causing the model to flag correct patterns as deadlocks

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.
Partnered with leading AI, data, and software stack.
How We Work
Custom AI workflows for your Business
One-fit-all AI don't work for modern businesses. At Inferensys, we aim to understand your business & custom requirements; which we use to define most efficient agentic workflows, the data, and the tools for your business.
01
Review the use case
We understand the task, the users, and where AI can actually help.
Read more02
Pick the right approach
We define what needs search, automation, or product integration.
Read more03
Build the first useful version
We implement the part that proves the value first.
Read more04
Improve from there
We add the checks and visibility needed to keep it useful.
Read moreThe first call is a practical review of your use case and the right next step.
Talk to Us