Use this prompt when you are building or maintaining a GraphQL gateway and need to enforce a consistent, spec-compliant response shape across multiple upstream resolvers or microservices. The primary job-to-be-done is wrapping partial or complete resolver outputs into a predictable envelope containing data, errors, and optional extensions fields, ensuring that any client consuming your graph can reliably parse both successful and failed responses. The ideal user is a backend engineer, platform architect, or API gateway developer who already understands the GraphQL specification's section on response format and needs a programmatic way to normalize outputs before they reach the client.
Prompt
GraphQL Response Envelope with Errors Array Prompt

When to Use This Prompt
Define the job, ideal user, required context, and constraints for standardizing GraphQL response envelopes.
This prompt is most valuable when your architecture involves stitching, federation, or a custom gateway layer where individual services may not produce GraphQL-compliant error shapes on their own. It is also appropriate when you need to inject extensions metadata—such as tracing IDs, cost analysis, or deprecation warnings—into every response without modifying each resolver. You should not use this prompt for designing the schema itself, for authoring resolver logic, or for handling transport-level concerns like HTTP status codes. It is strictly focused on shaping the JSON payload body after execution.
Before applying this prompt, ensure you have a clear specification for what constitutes a valid data payload, a defined error taxonomy (including message, locations, path, and extensions fields), and a decision on whether partial data is allowed alongside errors. The prompt works best when you provide concrete examples of malformed upstream responses and the desired corrected output. Avoid using this prompt as a substitute for proper resolver-level error handling; instead, treat it as the final normalization layer that guarantees every client receives a structurally valid GraphQL response. Proceed by gathering representative upstream payloads—both successful and error cases—and defining your exact extensions contract before wiring this into your gateway pipeline.
Use Case Fit
Where this prompt works, where it fails, and the operational preconditions required before wiring it into a GraphQL gateway.
Good Fit: GraphQL Gateway Standardization
Use when: you are building or maintaining a GraphQL gateway that must wrap multiple upstream services and return a consistent envelope shape. Guardrail: define the envelope contract (data, errors, extensions) once and enforce it across all resolver paths before adding model-generated payloads.
Bad Fit: Direct Database or Binary Responses
Avoid when: the downstream client expects raw binary, streaming multipart, or database wire-protocol responses. Guardrail: this prompt assumes a JSON-over-HTTP GraphQL transport; use a dedicated serialization layer for non-JSON response types.
Required Inputs
Risk: incomplete inputs produce envelopes with missing error paths, null location arrays, or orphaned extensions. Guardrail: require at minimum the operation result data, any resolver-level errors with path and locations, and optional extensions map before invoking the prompt.
Operational Risk: Partial Response Semantics
What to watch: GraphQL allows partial data alongside errors; the prompt must never drop valid data when errors are present. Guardrail: validate that the output preserves the data field even when the errors array is non-empty, matching GraphQL spec section 7.1.2.
Operational Risk: Error Path Array Drift
What to watch: error path arrays can reference nested fields, list indices, or aliases that shift across schema versions. Guardrail: cross-check error paths against the current schema's field map in your eval harness; flag any path that does not resolve to a valid field or index.
Operational Risk: Extensions Bloat
What to watch: teams often overload extensions with tracing, cost, and debugging metadata that leaks implementation details. Guardrail: strip or redact internal-only extension keys before the response leaves the gateway; keep a safelist of client-visible extension fields.
Copy-Ready Prompt Template
A reusable prompt template for generating GraphQL-compliant response envelopes with data, errors, and extensions fields.
This prompt template is designed to be wired into a GraphQL gateway or API orchestration layer. It instructs the model to produce a response envelope that strictly conforms to the GraphQL specification's requirements for the top-level data, errors, and extensions fields. The template uses square-bracket placeholders so you can inject the original query, upstream resolver results, partial error payloads, and any operational extensions before sending the request to the model.
textYou are a GraphQL response formatter. Your task is to construct a valid GraphQL response envelope from the provided inputs. You must follow the GraphQL specification (June 2018 edition) for the structure of the response map. ## Inputs - **GraphQL Query:** [GRAPHQL_QUERY] - **Resolver Results (JSON):** [RESOLVER_RESULTS] - **Upstream Errors (JSON Array, optional):** [UPSTREAM_ERRORS] - **Extensions (JSON Object, optional):** [EXTENSIONS] ## Output Schema Produce a single JSON object with the following top-level keys: - `data` (object or null): The successful response data. Must be `null` if no data is returned and errors are present. Must match the shape requested in the GraphQL query. - `errors` (array of objects, optional): An array of error objects if any errors occurred. Each error object must contain a `message` string. It may optionally contain `locations` (array of `{line, column}` objects), `path` (array of field names/indices), and `extensions` (object with a `code` string). - `extensions` (object, optional): A map for protocol extensions. If provided, merge the input [EXTENSIONS] here. ## Constraints - If [UPSTREAM_ERRORS] is provided and non-empty, the `errors` array must be populated. The `data` field should be `null` unless partial data is explicitly requested and available. - If a field in [RESOLVER_RESULTS] is `null` due to an error, that error must be represented in the `errors` array with a `path` reflecting the field's location in the query. - Do not include the key `errors` if there are no errors. - Ensure all `path` arrays use the correct string field names and integer indices as per the query. - The output must be a single, parseable JSON object with no surrounding text or markdown fences. ## Examples [EXAMPLES] ## Risk Level [RISK_LEVEL]
To adapt this template, replace the placeholders with data from your GraphQL execution engine. [RESOLVER_RESULTS] should be the partial or complete data map from your resolvers. [UPSTREAM_ERRORS] is the array of GraphQL errors you've already collected, which the model will normalize and de-duplicate. The [EXAMPLES] placeholder is critical for teaching the model how to handle edge cases like null propagation and list index paths; provide at least two few-shot examples showing a partial success scenario and a full error scenario. For high-risk operations, set [RISK_LEVEL] to HIGH and add a final instruction requiring a human to review the output before it is returned to the client.
Prompt Variables
Required and optional inputs for the GraphQL Response Envelope prompt. Each placeholder must be populated before the prompt is sent to the model. Validation notes describe how to check that the input is well-formed before generation.
| Placeholder | Purpose | Example | Validation Notes |
|---|---|---|---|
[GRAPHQL_QUERY] | The original GraphQL query string that triggered the response | query { user(id: 1) { name email } } | Parse check: must be valid GraphQL syntax. Null not allowed. Strip sensitive arguments before logging. |
[QUERY_VARIABLES] | JSON object containing variables passed with the query | {"id": 1, "includeInactive": false} | Parse check: valid JSON. Null allowed if query has no variables. Must match variable definitions in query. |
[RESOLVED_DATA] | The successfully resolved data payload from resolvers | {"user": {"name": "Ada", "email": "ada@example.com"}} | Parse check: valid JSON. Null allowed when no data resolved. Must match schema shape for queried fields. |
[ERRORS_ARRAY] | Array of error objects from resolver execution or validation | [{"message": "Field 'age' is deprecated", "path": ["user", "age"]}] | Parse check: valid JSON array. Each error must have 'message' string. 'path' and 'locations' optional. Null allowed for successful queries. |
[EXTENSIONS_OBJECT] | Optional metadata map for debugging, tracing, or custom protocol data | {"tracing": {"duration_ms": 42}, "cost": {"credits": 3}} | Parse check: valid JSON object. Null allowed. Keys must be strings. No reserved GraphQL extension names unless intentional. |
[OPERATION_NAME] | The operation name from the query, used for logging and trace context | "GetUserProfile" | String or null. Must match one operation name in the query document. Null for anonymous queries. |
[REQUEST_ID] | Unique identifier for the incoming request, used for correlation | "req_abc123xyz" | String. Must be non-empty. UUID format preferred. Used to populate extensions.requestId in output envelope. |
Implementation Harness Notes
How to wire the GraphQL response envelope prompt into a production gateway or API layer with validation, retries, and error handling.
This prompt is designed to sit inside a GraphQL gateway or API middleware layer that intercepts raw model outputs and reshapes them into a spec-compliant GraphQL response envelope. The primary integration point is a post-generation transformation step: the model produces structured content (data, errors, extensions), and your application layer validates, normalizes, and wraps that content before returning it to the client. Do not expose raw model output directly to GraphQL consumers—always pass it through this envelope layer to guarantee the data, errors, and extensions fields match your schema contract.
Wire the prompt into your application with a strict validation pipeline. After the model returns its JSON payload, run a validator that checks: (1) the root object contains exactly data, errors, and extensions keys with no extras; (2) data is either an object or null, never an array or scalar; (3) errors is an array where each element has a required message string and optional locations, path, and extensions fields; (4) path arrays contain only strings or integers; (5) locations arrays contain objects with line and column integers. If validation fails, log the raw output and the validation error, then retry with the same prompt plus the validator's error message appended as a correction instruction. After two retries, fall back to a safe error envelope: { "data": null, "errors": [{ "message": "Internal processing error" }], "extensions": {} }. For high-stakes production use, route outputs that fail validation to a human review queue rather than silently dropping them.
Model choice matters for this workflow. Use a model with strong JSON mode or structured output support (e.g., GPT-4 with response_format: { type: "json_object" }, Claude with tool-use mode, or any model that guarantees valid JSON output). Avoid models that frequently inject markdown fences or commentary outside the JSON block. If you must use a model without native JSON mode, add a post-processing step that extracts the first JSON object from the response using a regex or JSON parser before validation. For logging and observability, capture the prompt version, model ID, raw output, validation result, and final envelope in your tracing system. This makes it possible to debug partial response handling, error path accuracy, and location reference correctness when clients report issues.
When integrating with an existing GraphQL server, ensure the envelope prompt's output schema matches your server's ExecutionResult type exactly. If your server uses additional envelope fields (e.g., hasNext, subscriptionId for subscriptions), add those to the prompt's [OUTPUT_SCHEMA] placeholder. Test the integration with a suite of eval cases: a successful query returning only data, a query with field-level errors returning both data and errors, a completely failed query returning data: null with errors, and a query with extension metadata. Run these evals on every prompt change and model upgrade. The most common production failure mode is the model omitting the locations array on errors or using incorrect path segment types—add specific eval assertions for these cases.
Expected Output Contract
Validate the GraphQL response envelope structure, error array conformance, and partial response handling before integrating into your gateway.
| Field or Element | Type or Format | Required | Validation Rule |
|---|---|---|---|
data | object or null | Must be present at root. If null, errors array must be non-empty. If present, must be a valid object matching the requested query shape. | |
errors | array of objects | Must be present at root. If data is not null, errors may be empty. Each error object must contain a message string. | |
errors[].message | string | Non-empty string describing the error. Must not expose internal stack traces or database connection strings. | |
errors[].path | array of strings or integers | If present, each element must be a string (field name) or integer (list index). Must correspond to a valid path in the requested query. | |
errors[].locations | array of {line, column} objects | If present, each object must contain positive integer line and column fields. Must reference a valid location in the query document. | |
errors[].extensions | object | If present, must be a flat key-value map. Must not contain sensitive internal details. Use a code field for machine-readable error types. | |
extensions | object | If present, must be a flat key-value map at the root level. Use for tracing, latency, or custom metadata. Must not duplicate data or errors content. |
Common Failure Modes
GraphQL response envelopes must handle partial data, null fields, and error path arrays correctly. These failure modes break client parsing, error attribution, and spec compliance.
Missing `errors` Array on Partial Failure
What to watch: The model returns a data field with nulls for failed resolvers but omits the errors array entirely. Clients expecting to iterate over errors break with null-reference exceptions. Guardrail: Add a post-generation validator that checks: if any field in data is null and the field is non-nullable in the schema, the response MUST include a non-empty errors array with matching path entries.
Incorrect `path` Array Construction
What to watch: The model generates error paths as dot-separated strings ("user.address.city") instead of path arrays (["user", "address", "city"]). GraphQL clients cannot resolve string paths to field locations. Guardrail: Include a strict schema constraint in the prompt: "path" must be an array of strings. Validate with a JSON Schema check that rejects any string-typed path values before returning the response.
`data` Present When It Should Be Null
What to watch: On a top-level failure where no data can be returned, the model includes "data": {} instead of "data": null. This violates the GraphQL spec and causes clients to misinterpret an empty success payload. Guardrail: Add a conditional rule in the prompt: if the operation failed before any resolver executed, set "data" to null. Validate with a test case that triggers a top-level error and asserts response.data === null.
Missing `locations` on Syntax or Validation Errors
What to watch: The model returns query-level errors (syntax, validation) without locations arrays containing line and column. Tooling that highlights error positions in the query editor breaks silently. Guardrail: For errors with "extensions": { "code": "GRAPHQL_VALIDATION_FAILED" } or similar, require locations in the prompt schema. Post-process: if extensions.code indicates a query-level error and locations is absent, reject the response.
`extensions` Object Leaking Internal State
What to watch: The model copies raw exception messages, stack traces, or database errors into extensions fields. This leaks implementation details to clients and creates security vulnerabilities. Guardrail: Constrain extensions to an allowlist in the prompt: only code, timestamp, and requestId are permitted. Add a sanitization step that strips any unrecognized extension keys before returning the response to the client.
Inconsistent Nullability Across Partial Responses
What to watch: When some resolvers succeed and others fail, the model returns null for failed fields but also omits optional fields that should have been present. Clients cannot distinguish between "field is null because it errored" and "field is null because it was never requested." Guardrail: Instruct the model to preserve all requested fields in data, using null only for fields whose resolvers explicitly failed. Validate that the set of top-level keys in data matches the requested query fields exactly.
Evaluation Rubric
Criteria for evaluating whether a generated GraphQL response envelope conforms to the specification, handles errors correctly, and is safe for production use. Use these tests before shipping any prompt change.
| Criterion | Pass Standard | Failure Signal | Test Method |
|---|---|---|---|
Top-level structure compliance | Output is a valid JSON object containing exactly the keys 'data', 'errors', and 'extensions' with no additional top-level keys | Missing required key, extra top-level keys present, or output is not parseable JSON | Schema validation: parse output with JSON parser, assert Object.keys(output).sort() equals ['data','errors','extensions'].sort() |
Mutual exclusion of data and errors | When 'errors' array is non-empty, 'data' field must be null; when 'data' is non-null, 'errors' must be absent or an empty array | Both 'data' and 'errors' contain meaningful values simultaneously, violating GraphQL spec section 7.1.2 | Assertion: if output.errors.length > 0 then output.data === null; if output.data !== null then (!output.errors || output.errors.length === 0) |
Error object structure | Each element in 'errors' array contains a 'message' string; optional fields 'locations', 'path', and 'extensions' are correctly typed when present | Error object missing 'message', 'locations' is not an array of {line,column} objects, or 'path' is not an array of strings/integers | Iterate output.errors, assert typeof error.message === 'string', assert !error.locations || Array.isArray(error.locations), assert !error.path || Array.isArray(error.path) |
Partial response handling | When partial data is returned alongside errors, 'data' contains available fields set to null for failed resolvers, and 'errors' includes path references to the failed fields | Non-nullable field error causes entire 'data' to be null instead of nulling only the failed field, or error paths don't match the nulled fields in data | Provide input that triggers a resolver failure on a nullable field; assert output.data.field === null and output.errors[0].path includes the field name |
Extensions field structure | 'extensions' field, when present, is a JSON object (map) containing implementation-specific metadata such as tracing, cost, or deprecation warnings | 'extensions' is an array, string, or primitive instead of an object; or contains keys that collide with reserved GraphQL extension names | Assert typeof output.extensions === 'object' && !Array.isArray(output.extensions) && output.extensions !== null |
Empty response handling | When query returns no data and no errors, 'data' is null and 'errors' is an empty array or absent | 'data' is an empty object {} instead of null, or 'errors' contains a generic error for a valid empty result | Submit a valid query that resolves to no data; assert output.data === null and (!output.errors || output.errors.length === 0) |
Field-level error isolation | An error in one resolver does not prevent sibling resolvers from returning data; only the errored field and its children are nulled | Single resolver failure causes entire 'data' object to be null or all sibling fields to be missing | Submit query with multiple top-level fields where one resolver fails; assert output.data contains non-null values for successful fields and null for the failed field |
Serialization safety | Output contains no circular references, undefined values, or non-serializable types (functions, symbols, BigInt) | JSON.stringify throws TypeError due to circular reference or unsupported value type | Execute JSON.stringify(output) inside a try-catch; assert no exception is thrown and result is a valid string |
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
Add full schema validation with JSON Schema or Zod before the response leaves the gateway. Include retry logic for malformed envelopes. Log every envelope that fails validation.
codeYou must return a JSON object with exactly three top-level keys: - `data`: [RESULT_SCHEMA] or null - `errors`: array of error objects with `message`, `path`, `locations`, and `extensions` fields - `extensions`: object with `requestId` and `cost` fields
Watch for
- Silent format drift after model updates
dataanderrorsboth null simultaneouslypatharray using inconsistent index formats

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