{"record":{"id":"1dd61cc34d606d31","repo":"dagger/dagger","slug":"no-field-has-been-selected","errorCode":null,"errorMessage":"No field has been selected","messagePattern":"No field has been selected","errorType":"exception","errorClass":"InvalidQueryError","httpStatus":null,"severity":"error","filePath":"sdk/python/src/dagger/client/_core.py","lineNumber":165,"sourceCode":"        return ctx.select(\"Query\", field_name, args)\n\n    def select_id(self, type_name: str, id_value: str) -> \"Context\":\n        \"\"\"Load an object by its ID via node(id:) with an inline fragment.\"\"\"\n        ctx = dataclasses.replace(self, selections=collections.deque())\n        node_field = Field(\n            type_name=\"Query\",\n            name=\"node\",\n            args={\"id\": id_value},\n            inline_type=type_name,\n        )\n        selections = ctx.selections.copy()\n        selections.append(node_field)\n        return dataclasses.replace(ctx, selections=selections)\n\n    async def build(self) -> DSLSelectable:\n        if not self.selections:\n            msg = \"No field has been selected\"\n            raise InvalidQueryError(msg)\n\n        def _collapse(child: Field, field_: Field):\n            return field_.add_child(child)\n\n        # This transforms the selection set into a single root Field, where\n        # the `children` attribute is set to the next selection in the set,\n        # and so on...\n        root = functools.reduce(_collapse, reversed(self.selections))\n\n        # `to_dsl` will cascade to all children, until the end.\n        try:\n            return root.to_dsl(DSLSchema(await self.conn.session.get_schema()))\n        except (graphql.GraphQLError, AttributeError, TypeError) as e:\n            logger.exception(\"GraphQL query builder failed to build query\")\n            msg = (\n                \"Failed to build GraphQL query, probably due to a schema validation \"\n                \"issue. Please file a bug report because anything that could \"\n                \"fail to validate at this point should really happen sooner. \"","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/dagger/dagger/blob/82ba2681dbe30d3547a1dc50ea495900ab5b6047/sdk/python/src/dagger/client/_core.py#L147-L183","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\nq = client.query()\nif include_version:\n    q = q.select(\"version\")\nresult = await q.execute()  # InvalidQueryError when include_version is False\n# after\nq = client.query().select(\"version\")  # always select a base field\nresult = await q.execute()","handlingStrategy":"validation","validationCode":"def is_executable(q) -> bool:\n    return bool(getattr(q, '_ctx', None) and getattr(q._ctx, 'selections', None))\n\nif not is_executable(client.query()):\n    raise RuntimeError('query has no fields selected')","typeGuard":"def has_selections(q) -> bool:\n    ctx = getattr(q, '_ctx', None)\n    return bool(ctx and getattr(ctx, 'selections', None))","tryCatchPattern":"try:\n    result = await q.execute()\nexcept dagger.InvalidQueryError:\n    raise RuntimeError('no field selected on query; call at least one field before execute')","preventionTips":["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"],"tags":["python","dagger-client","graphql","invalid-query"],"backgroundTag":"empty-graphql-selection-set","analyzedSha":"82ba2681dbe30d3547a1dc50ea495900ab5b6047","analyzedAt":"2026-09-05T07:21:37.930Z","contentChangedAt":"2026-09-05T07:21:37.930Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}