unbounded-query

Detects and triages unbounded AEM queries that cause out-of-memory failures.

1|Updated Jun 22, 2026
One-click install
npx skills add https://github.com/aemgdc/aemdev --skill unbounded-query-aemgdc
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: unbounded-query
Source: https://github.com/aemgdc/aemdev/tree/main/.agents/skills/unbounded-query
Command: npx skills add https://github.com/aemgdc/aemdev --skill unbounded-query-aemgdc

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill includes scripts (resource) and references (resource) components.

What problem does it solve? Unbounded AEM queries (p.limit=-1 or setLimit(-1)) load entire result sets into heap, and when iterated in a loop they cause out-of-memory outages — the top OOM cause in AEM Cloud Service. This Skill finds those queries and fixes them safely without silently dropping rows. ## Core Features & Use Cases - Precise detection: Flags the two explicit unbounded markers — QueryBuilder p.limit=-1 predicate entries and JCR setLimit(-1) calls — including same-file constant references. - Consumption-based triage: Classifies each finding by how results are consumed (single-result, bounded list, iterate-all) and applies the safe fix: bound to 1, bound to N, or wrap in an offset paging loop. - Safe escalation: Request-path iterate-all queries are flagged as needs-pagination for human review rather than silently capped, preventing silent data truncation bugs. - Use Case: A scan flags p.limit=-1 in your search component after an OOM incident. The Skill reads the consuming method, bounds a single-result lookup to 1, and escalates a cross-method iterate-all query with a pagination recommendation. ## Quick Start Ask the assistant to scan my AEM project for unbounded queries and fix or flag each one based on how the results are consumed.

Frequently Asked Questions about unbounded-query

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I fix an unbounded query in AEM causing OutOfMemoryError?▼

First identify how the result is consumed. Single-result lookups can be bounded to 1, top-N lists to their display size, and iterate-all cases need offset paging loops. Request-path queries that read all rows should be escalated for human pagination rather than silently capped.

What does p.limit=-1 do in AEM QueryBuilder?▼

The p.limit=-1 predicate tells QueryBuilder to return every matching row, loading the entire result set into heap. When those results are traversed in a loop, the heap fills and the instance can OOM, making it a leading cause of AEM Cloud Service memory outages.

Why shouldn't I just cap p.limit=-1 to a fixed number?▼

Capping is not behavior-neutral: if the real result exceeds the cap, rows are silently dropped, causing wrong counts and truncated lists. Only cap where the caller provably reads a bounded subset; otherwise add offset paging or escalate for a human decision.

Does this handle JCR setLimit(-1) as well as QueryBuilder?▼

Yes, the detector flags both explicit markers: QueryBuilder predicate entries put("p.limit", "-1") and JCR query.setLimit(-1) calls, including values passed through same-file final constants. Bounded queries and -1 values on other keys are not flagged.

When are unbounded query findings skipped instead of fixed?▼

Findings are skipped with recorded reasons when the query runs on the request path consuming all rows (needs-pagination), when it is an off-request batch job needing the full set, or when it is test code under src/test. Skips are surfaced in the report, never silently dropped.