Complete Guide to JMESPath Tester: Master Filters, Projections, and Functions
Learn to write and debug JMESPath queries against real JSON payloads. Master filters, projections, multiselect, and built-in functions with instant results, clear syntax errors, and matched paths.
Table of Contents
Complete Guide to JMESPath Tester: Master Filters, Projections, and Functions
If you have ever piped an AWS CLI command through --query or pulled a nested field out of a boto3 response, you have already used JMESPath β whether you knew its name or not. JMESPath is the declarative query language built into the AWS CLI, boto3, the AWS SDKs, Ansible, and dozens of other tools. It walks a JSON document and selects the values you need with one compact expression instead of a loop.
The catch is that JMESPath is a real language with its own grammar. A misplaced bracket in a filter or a forgotten wildcard can return null, an empty list, or a cryptic syntax error. Guessing rarely works; testing against a realistic payload does.
That is exactly what the free JMESPath Tester is for. Paste your JSON, type a query, and see results, matched values, and syntax errors with positions β instantly, entirely in your browser. This guide moves from dot notation to filters, projections, multiselects, and functions on one realistic payload.
Why Use JMESPath Tester?
- Instant feedback loop: results update as you type, so you can experiment with filter and projection syntax in seconds.
- Clear syntax errors with positions: invalid queries report the error and where it occurs, turning cryptic failures into a ten-second fix.
- Matched values and paths: beyond the final result you see which paths matched, making complex projections understandable.
- One hundred percent client-side: JSON never leaves your machine, so payloads with real identifiers or sensitive fields are safe to test.
- Works offline: once loaded, no network connection is needed β handy over a VPN or on an air-gapped workstation.
- A safe rehearsal for production queries: validate an expression before it lands in a script, a CI job, or a runbook.
Key Features
| Feature | What It Does | Why It Matters |
|---|---|---|
| Instant evaluation | Runs your query against the pasted JSON as you type | No save-reload cycle while you experiment |
| Filter expressions | Supports conditions such as [?state == 'running'] | Select only the items you actually care about |
| Projections | Flattens lists and objects with [], [*], and * | Apply one expression to every element at once |
| Multiselect | Builds lists and hashes such as {id: id, name: name} | Reshape documents into exactly the output you need |
| Built-in functions | sort(), length(), keys(), not_null(), and friends | Count, order, and transform without extra tooling |
| Error reporting | Syntax errors reported with positions | Fix queries fast instead of staring at null |
Two details go beyond the table:
- Everything runs in the browser β nothing to install, no account to create.
- The result panel distinguishes between "no match" and "syntax error", a difference that matters more than it sounds.
How to Use
- Open the tester at the JMESPath Tester page. It loads instantly and keeps working offline afterwards.
- Paste your JSON document into the input panel. Any valid JSON works: an API response, a CLI output, a config file, a log record.
- Write your JMESPath query in the query box. Start small with a plain identifier such as instances[0].name, then grow it one step at a time.
- Read the result. Matched values appear immediately; if the query has a syntax problem, the error and its position appear instead.
- Iterate and copy. Compare a few variants, then copy the winning query into your CLI command, SDK call, or script.
From Dot Notation to Projections
To keep things concrete, this section uses one trimmed, EC2-style payload throughout.
{
"instances": [
{ "id": "i-0a1b", "name": "web-01", "state": "running", "score": 61 },
{ "id": "i-2c3d", "name": "db-01", "state": "running", "score": 42 },
{ "id": "i-4e5f", "name": "web-02", "state": "stopped", "score": 78 }
]
}
Start with Identifiers and Pipes
The simplest query just walks keys: instances[0].name returns "web-01". Dotted identifiers drill into nested documents, and the pipe operator | feeds the current result into the next expression β how you combine steps that would otherwise conflict.
Filter with Conditions in Brackets
Filters select only elements satisfying a condition: instances[?state == 'running'].id returns ["i-0a1b", "i-2c3d"]. String literals use single quotes; numeric literals traditionally use backticks, as in [?score > `50`] β many engines also accept bare numbers, and the tester tells you immediately which form yours supports.
Projections: Every Element at Once
instances[*].id (the same as instances[].id) projects the right-hand expression over every element, returning ["i-0a1b", "i-2c3d", "i-4e5f"]. Wildcards also work over objects, reaching every value of a map without knowing its keys.
Multiselect: Reshape the Document
A multiselect builds a new structure from each match. A hash multiselect such as instances[*].{id: id, name: name} returns one small object per instance instead of the whole document β the workhorse for slimming fat API responses down to the fields your code actually reads.
Functions: sort, length, and Friends
Built-in functions add computation to selection. length(instances) returns 3; sort(instances[*].score) returns [42, 61, 78]. You can pipe into them too: instances[*].score | sort(@) sorts the projected list, where @ means "the current result".
Why Results Flatten After Projections
Here is the most common surprise in the whole language. When you project over a projection β say every instance has a tags list and you write instances[*].tags[*] β JMESPath does not nest the arrays; the inner projection flattens into a single list of all tags. If you expected [[...], [...]] and got one flat array, that is projection flattening at work, not a bug. If you want the structure preserved, use a multiselect instead of a second projection.
Three Progressive Queries on the Same Payload
1) instances[?state == 'running'].name
-> ["web-01", "db-01"]
2) instances[?score > `50`].{name: name, score: score}
-> [{"name": "web-01", "score": 61}, {"name": "web-02", "score": 78}]
3) instances[*].score | sort(@) | [-1]
-> 78 (the highest score)
Query 1 filters, query 2 filters and reshapes, and query 3 projects, sorts, and indexes, all from the same little document.
Practical Use Cases
Writing AWS CLI --query Expressions
The --query flag accepts exactly this language, so the tester is a rehearsal stage for CLI commands. Expressions such as Reservations[].Instances[].InstanceId behave surprisingly because of projection flattening; verifying them against a saved sample prevents painful re-parsing.
Extracting Fields from Large API Responses
When a response is thousands of lines deep, a projection plus multiselect reduces it to the fields you need for a report or test fixture. Pair the tester with the JSON Formatter to explore structure first, then query what you found.
Log and Message Filtering
Structured logs, CloudWatch-style events, and queue messages are all JSON. A small library of tested queries β errors only, slow requests above a threshold, records missing a field β turns triage into a repeatable routine.
Data Pipeline Spot Checks
Before a transformation ships, run its input and expected output shapes through the tester. If the expression returns what you expect on a representative sample, you have removed a whole class of silent failures.
Best Practices
- Test against production-shaped samples, not two-element toy arrays. Edge cases such as empty lists and missing keys only appear in realistic payloads.
- Watch flattened results after projections. If a query returns more or fewer items than expected, flattening is usually the reason.
- Quote identifiers with special characters using double quotes β "order-id", "user.name" β whenever a key contains dashes, dots, or spaces.
- Remember null semantics: JMESPath returns null for missing keys rather than raising an error, so a silent null usually means a typo in an identifier.
- Keep winning queries in team docs next to the commands that use them.
- Prefer hash multiselects for anything you hand to another system β a stable output shape beats "whatever the source returned".
Ready to stop guessing? Open the JMESPath Tester, paste a real payload, and iterate until the expression is exactly right.
Related Tools You Might Like:
- jq Playground β practice jq, JMESPath's close cousin, with the same instant feedback.
- JSON Formatter β prettify and inspect the payloads you are about to query.
- GraphQL Formatter β format and review GraphQL queries with the same care.
Happy querying β may your projections always flatten the way you expect.
Frequently Asked Questions
Q: Is my JSON sent to a server?
A: No. Parsing and evaluation happen entirely in your browser. The tool is one hundred percent client-side, so sensitive payloads never leave your machine, and it keeps working offline once loaded.
Q: How is JMESPath different from jq?
A: Both query JSON documents. JMESPath is a standardized spec embedded in AWS tooling, boto3, and many SDKs. jq has its own larger language with more features, at the cost of a steeper learning curve.
Q: Why does my query return null instead of an error?
A: JMESPath returns null when a key does not exist rather than raising an error. A silent null almost always means a misspelled identifier or a wrong nesting level. Filters return an empty list when nothing matches.
Q: Do numeric comparisons need backticks in filters?
A: In strict JMESPath, comparison literals are raw literals in backticks, like [?score > `50`]. Many implementations also accept bare numbers; the tester shows you immediately which form your engine accepts.
Q: Can I use it without an internet connection?
A: Yes. After the page loads, everything β parsing, evaluation, and error reporting β runs locally in your browser with no server round-trips.