dagger/dagger · error · InvalidQueryError
No field has been selected
Error message
No field has been selected
What it means
The Python Dagger client builds GraphQL queries incrementally by appending selections to a context. Query.build() refuses to serialize a query with zero selections, raising InvalidQueryError("No field has been selected"), because a selection set with no fields is not a valid GraphQL request.
Source
Thrown at sdk/python/src/dagger/client/_core.py:165
return ctx.select("Query", field_name, args)
def select_id(self, type_name: str, id_value: str) -> "Context":
"""Load an object by its ID via node(id:) with an inline fragment."""
ctx = dataclasses.replace(self, selections=collections.deque())
node_field = Field(
type_name="Query",
name="node",
args={"id": id_value},
inline_type=type_name,
)
selections = ctx.selections.copy()
selections.append(node_field)
return dataclasses.replace(ctx, selections=selections)
async def build(self) -> DSLSelectable:
if not self.selections:
msg = "No field has been selected"
raise InvalidQueryError(msg)
def _collapse(child: Field, field_: Field):
return field_.add_child(child)
# This transforms the selection set into a single root Field, where
# the `children` attribute is set to the next selection in the set,
# and so on...
root = functools.reduce(_collapse, reversed(self.selections))
# `to_dsl` will cascade to all children, until the end.
try:
return root.to_dsl(DSLSchema(await self.conn.session.get_schema()))
except (graphql.GraphQLError, AttributeError, TypeError) as e:
logger.exception("GraphQL query builder failed to build query")
msg = (
"Failed to build GraphQL query, probably due to a schema validation "
"issue. Please file a bug report because anything that could "
"fail to validate at this point should really happen sooner. "View on GitHub (pinned to 82ba2681db)
Solutions
- Ensure at least one field is selected before executing, e.g. `await client.query().version` or `.container().id()`
- If fields are conditional, guarantee a default field or raise earlier when none apply
- Check you're awaiting the final field object, not the intermediate query builder
- For dynamic code, assert the selections were added before execute
Example fix
# before
q = client.query()
if include_version:
q = q.select("version")
result = await q.execute() # InvalidQueryError when include_version is False
# after
q = client.query().select("version") # always select a base field
result = await q.execute() Defensive patterns
Strategy: validation
Validate before calling
def is_executable(q) -> bool:
return bool(getattr(q, '_ctx', None) and getattr(q._ctx, 'selections', None))
if not is_executable(client.query()):
raise RuntimeError('query has no fields selected') Type guard
def has_selections(q) -> bool:
ctx = getattr(q, '_ctx', None)
return bool(ctx and getattr(ctx, 'selections', None)) Try / catch
try:
result = await q.execute()
except dagger.InvalidQueryError:
raise RuntimeError('no field selected on query; call at least one field before execute') Prevention
- Always select at least one field (e.g. .id(), .version) before awaiting a query
- Await the final field object, not intermediate builders
- When building queries conditionally, include a default field or fail early if none apply
When it happens
Trigger: Calling `await`/`execute` (which triggers build via request) on a client/query object that never had a field selected — e.g. `client.query().execute()`, awaiting an empty sub-selection, or constructing a Client/Root manually without `.some_field()` calls.
Common situations: Dynamically building queries with conditional field calls where every branch was skipped, chaining mistakes like `client.query()` assigned but fields appended to a different object, or awaiting an intermediate object instead of the final field.
Related errors
- Errors list is empty
- Failed to build GraphQL query, probably due to a schema vali
- Failed to build schema from introspection query: {msg}
- No schema in session
- merge module types into schema: %w
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/1dd61cc34d606d31.
Report an issue: GitHub.