dagger/dagger · error · InvalidQueryError

Required field got a null response. Check if parent fields a

Error message

Required field got a null response. Check if parent fields are valid.

What it means

Raised as InvalidQueryError in get_value() when the engine's response contains null for a field whose declared Python return type does not allow None (type_hint.is_bearable(value) is False). The SDK surfaces it as a contract violation: either the queried field legitimately resolved to null in the engine (e.g. the parent object doesn't exist) or the response shape didn't match the selections.

Source

Thrown at sdk/python/src/dagger/client/_core.py:290

    @overload
    def get_value(self, value: None, return_type: Any) -> None: ...

    @overload
    def get_value(self, value: dict[str, Any], return_type: type[T]) -> T: ...

    def get_value(self, value: dict[str, Any] | None, return_type: type[T]) -> T | None:
        type_hint = TypeHint(return_type)

        for f in self.selections:
            if not isinstance(value, dict):
                break
            value = value[f.name]

        if value is None and not type_hint.is_bearable(value):
            msg = (
                "Required field got a null response. Check if parent fields are valid."
            )
            raise InvalidQueryError(msg)

        return self.converter.structure(value, return_type)

    def handle_group_err(self, grp: exceptiongroup.BaseExceptionGroup):
        """Handle exception group errors."""
        # just re-raise the first one
        for exc in grp.exceptions:
            raise exc from None

    async def resolve_ids(self) -> None:
        """Replace Type object instances with their ID implicitly."""

        # mutating to avoid re-fetching on forked pipeline
        async def _resolve_id(pos: int, k: str, v: IDType):
            sel = self.selections[pos]
            sel.args[k] = await v.id()

        async def _resolve_seq_id(pos: int, idx: int, k: str, v: IDType):

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Check the parent chain: confirm the container/image/host path the field derives from actually exists before executing (e.g. verify the file path or base image tag).
  2. Change the return type to Optional (e.g. `await ctx.execute(str | None)`) and handle the None case explicitly, as the SDK itself does in execute_object().
  3. Add error handling or validation for missing inputs (file existence, image availability) before querying the field.
  4. If you believe the field should never be null, inspect the raw response (enable Config(log_output)/debug logging) and report a possible SDK/engine schema mismatch.

Example fix

# before: assumes value always present, crashes on null
out = await client.container().from_("alpine").file("/etc/hosts").contents()  # or: execute(str)

# after: allow None and handle it
colors = await client.container().from_("alpine").file("/maybe-missing").contents()
# or with explicit execute:
value = await ctx.execute(str | None)
if value is None:
    value = ""  # fallback
Defensive patterns

Strategy: type-guard

Validate before calling

# validate the parent object exists / input is valid before querying
import sys
async def file_contents_or_none(client, path: str) -> str | None:
    ctr = client.container().from_("alpine")
    return await ctr.file(path).contents() if path else None

Type guard

from typing import TypeGuard
def value_present(value: object) -> TypeGuard[str]:
    return value is not None and value != ""

Try / catch

try:
    value = await ctx.execute(str)
except dagger.InvalidQueryError:
    value = None  # field resolved to null; handle missing case

Prevention

When it happens

Trigger: Querying a nullable-when-invalid field on a nonexistent parent (e.g. `.container().file("/missing")` style lookups, platform-specific fields returning null), calling `execute(SomeType)` with a non-Optional return_type while the engine returns null; using a stale/failed object handle whose parent field resolved to null.

Common situations: Requesting a file or secret that doesn't exist in the container/image so the parent field is null; building on an empty or misconfigured base image; `execute(str)` on a field that can be null while the user expected a value; type mismatches between the declared return_type and the actual GraphQL field nullability.

Related errors


AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05). Data as JSON: /api/errors/a6037d45ee223480. Report an issue: GitHub.