mvanhorn/last30days-skill · error · ValueError
subqueries[{index}].{field} must be a non-empty string
Error message
subqueries[{index}].{field} must be a non-empty string What it means
Field check inside each subquery object: 'search_query' and 'ranking_query' must both be non-empty strings (after strip). Both are required per subquery — search_query drives retrieval, ranking_query drives relevance scoring, so one without the other is an incomplete contract.
Source
Thrown at skills/last30days/scripts/lib/planner.py:197
if source_weights is not None and not isinstance(source_weights, dict):
raise ValueError("field 'source_weights' must be an object when provided")
for source, weight in (source_weights or {}).items():
if (
not isinstance(source, str)
or not source.strip()
or isinstance(weight, bool)
or not isinstance(weight, (int, float))
):
raise ValueError("field 'source_weights' must map source names to numbers")
subqueries = raw["subqueries"]
if not isinstance(subqueries, list) or not subqueries:
raise ValueError("field 'subqueries' must be a non-empty array")
for index, subquery in enumerate(subqueries):
if not isinstance(subquery, dict):
raise ValueError(f"subqueries[{index}] must be an object")
for field in ("search_query", "ranking_query"):
if not isinstance(subquery.get(field), str) or not subquery[field].strip():
raise ValueError(f"subqueries[{index}].{field} must be a non-empty string")
sources = subquery.get("sources")
if not isinstance(sources, list) or not sources or not all(
isinstance(source, str) and source.strip() for source in sources
):
raise ValueError(f"subqueries[{index}].sources must be a non-empty string array")
weight = subquery.get("weight")
if weight is not None and (
isinstance(weight, bool) or not isinstance(weight, (int, float))
):
raise ValueError(f"subqueries[{index}].weight must be a number when provided")
DEFAULT_INTENT_CAPABILITIES = {
"comparison": {"discussion", "video", "web", "reference", "social", "link", "market"},
"how_to": {"discussion", "video", "web", "reference", "link"},
}
View on GitHub (pinned to c7460f6114)
Solutions
- Set ranking_query equal to search_query if you have no separate ranking terms.
- Reject/repair subqueries where either field is missing or blank before submitting.
- Validate in your emitter: all(isinstance(sq.get(f), str) and sq[f].strip() for f in ('search_query','ranking_query')).
Example fix
# before
{"search_query": "zig vs rust", "sources": ["reddit"]}
# after
{"search_query": "zig vs rust", "ranking_query": "zig vs rust performance", "sources": ["reddit"]} Defensive patterns
Strategy: validation
Validate before calling
for i, q in enumerate(plan["subqueries"]):
for f in ("search_query", "ranking_query"):
v = q.get(f)
if not isinstance(v, str) or not v.strip():
q[f] = q.get("search_query", "") or q.get("ranking_query", "") # mirror the other field
if not q[f].strip():
raise SystemExit(f"subqueries[{i}] lacks usable queries") Type guard
def has_query_pair(q: dict) -> bool:
return all(isinstance(q.get(f), str) and q[f].strip() for f in ("search_query", "ranking_query")) Prevention
- Default ranking_query to search_query when no separate ranking terms exist.
- Lint generated plans for both fields before submission.
When it happens
Trigger: A subquery missing ranking_query, or with search_query: "" / " " / null / a number. The error names the index and the failing field.
Common situations: Generators that only fill search_query and skip ranking_query; whitespace placeholder values; nulls for 'no ranking needed'.
Related errors
- top-level plan must be an object
- missing required field '{field}'
- field '{field}' must be a non-empty string
- field 'source_weights' must be an object when provided
- field 'source_weights' must map source names to numbers
AI-assisted analysis of mvanhorn/last30days-skill@c7460f6114 (2026-08-15).
Data as JSON: /api/errors/0735ea5c385fe87a.
Report an issue: GitHub.