{"record":{"id":"a6037d45ee223480","repo":"dagger/dagger","slug":"required-field-got-a-null-response-check-if-paren","errorCode":null,"errorMessage":"Required field got a null response. Check if parent fields are valid.","messagePattern":"Required field got a null response\\. Check if parent fields are valid\\.","errorType":"exception","errorClass":"InvalidQueryError","httpStatus":null,"severity":"error","filePath":"sdk/python/src/dagger/client/_core.py","lineNumber":290,"sourceCode":"    @overload\n    def get_value(self, value: None, return_type: Any) -> None: ...\n\n    @overload\n    def get_value(self, value: dict[str, Any], return_type: type[T]) -> T: ...\n\n    def get_value(self, value: dict[str, Any] | None, return_type: type[T]) -> T | None:\n        type_hint = TypeHint(return_type)\n\n        for f in self.selections:\n            if not isinstance(value, dict):\n                break\n            value = value[f.name]\n\n        if value is None and not type_hint.is_bearable(value):\n            msg = (\n                \"Required field got a null response. Check if parent fields are valid.\"\n            )\n            raise InvalidQueryError(msg)\n\n        return self.converter.structure(value, return_type)\n\n    def handle_group_err(self, grp: exceptiongroup.BaseExceptionGroup):\n        \"\"\"Handle exception group errors.\"\"\"\n        # just re-raise the first one\n        for exc in grp.exceptions:\n            raise exc from None\n\n    async def resolve_ids(self) -> None:\n        \"\"\"Replace Type object instances with their ID implicitly.\"\"\"\n\n        # mutating to avoid re-fetching on forked pipeline\n        async def _resolve_id(pos: int, k: str, v: IDType):\n            sel = self.selections[pos]\n            sel.args[k] = await v.id()\n\n        async def _resolve_seq_id(pos: int, idx: int, k: str, v: IDType):","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/dagger/dagger/blob/82ba2681dbe30d3547a1dc50ea495900ab5b6047/sdk/python/src/dagger/client/_core.py#L272-L308","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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).","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().","Add error handling or validation for missing inputs (file existence, image availability) before querying the field.","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."],"exampleFix":"# before: assumes value always present, crashes on null\nout = await client.container().from_(\"alpine\").file(\"/etc/hosts\").contents()  # or: execute(str)\n\n# after: allow None and handle it\ncolors = await client.container().from_(\"alpine\").file(\"/maybe-missing\").contents()\n# or with explicit execute:\nvalue = await ctx.execute(str | None)\nif value is None:\n    value = \"\"  # fallback","handlingStrategy":"type-guard","validationCode":"# validate the parent object exists / input is valid before querying\nimport sys\nasync def file_contents_or_none(client, path: str) -> str | None:\n    ctr = client.container().from_(\"alpine\")\n    return await ctr.file(path).contents() if path else None","typeGuard":"from typing import TypeGuard\ndef value_present(value: object) -> TypeGuard[str]:\n    return value is not None and value != \"\"","tryCatchPattern":"try:\n    value = await ctx.execute(str)\nexcept dagger.InvalidQueryError:\n    value = None  # field resolved to null; handle missing case","preventionTips":["Declare nullable return types (str | None) when the GraphQL field can legitimately be null.","Validate parent inputs (file paths, image refs, secret names) before querying child fields.","Use the Optional-returning pattern the SDK itself uses (execute_object) for possibly-absent objects.","Enable logging to inspect raw responses when nullability expectations don't match reality."],"tags":["null","graphql","type-safety","query"],"backgroundTag":"unexpected-null-value","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"}