Skip to content

Raise a clear error for unknown TypedDict fields in extract_fields - #1733

Open
breken-ai wants to merge 1 commit into
apache:mainfrom
breken-ai:fix/extract-fields-typeddict-unknown-field
Open

breken-ai wants to merge 1 commit into
apache:mainfrom
breken-ai:fix/extract-fields-typeddict-unknown-field

Conversation

@breken-ai

Copy link
Copy Markdown

When @extract_fields gets a list of field names and the function returns a TypedDict, a name that is not in the TypedDict is recorded in errors. It is then looked up anyway on the next line. Users get a bare KeyError at graph-build time instead of the InvalidDecoratorException that lists the invalid fields.

class MyDict(TypedDict):
    test: int

@extract_fields(["test", "tset"])
def d() -> MyDict: ...

# on main: KeyError: 'tset'
# expected: InvalidDecoratorException: ... The following fields were not valid:
#           ["tset is not a field in the `TypedDict` ..."]

The dict form (extract_fields({"tset": int})) already reports this properly, because that branch continues after recording the error.

Changes

  • hamilton/function_modifiers/expanders.py: in _determine_fields_to_extract, continue after recording an unknown field, matching the dict branch just below it.
  • tests/function_modifiers/test_expanders.py: one more case in test_extract_fields_invalid_annotations_for_inferred_types, ("MyDict", (["test", "not_a_field"])).

How I tested this

  • New case on unmodified main (661aa888): fails with KeyError: 'not_a_field'.
  • With the fix, it passes (the expected InvalidDecoratorException is raised).
  • pytest tests/function_modifiers tests/test_function_modifiers.py tests/test_end_to_end.py tests/test_hamilton_driver.py tests/test_async_driver.py: 528 passed.
  • ruff check and ruff format --check (0.15.14) are clean. git diff --check is clean.

Notes

This was introduced with the list-of-names support for TypedDict in d601a92 (2025-07).

Checklist

  • PR has an informative and human-readable title (this will be pulled into the release notes)
  • Changes are limited to a single goal (no scope creep)
  • Code passed the pre-commit check & code is left cleaner/nicer than when first encountered.
  • Any change in functionality is tested
  • New functions are documented (with a description, list of inputs, and expected output) — no new functions
  • Placeholder code is flagged / future TODOs are captured in comments — none added
  • Project documentation has been updated if adding/changing functionality — no documented behavior changes; this makes the code match the existing docs

AI disclosure (per the ASF Generative Tooling guidance): this change was written with an AI coding tool (Claude Code, Claude Opus 5.5) working through the breken-ai account. The tool found the bug, wrote the fix and the test, and wrote this description. The commit carries a Generated-by: trailer. The diff is a small original change to existing Hamilton code and includes no third-party material. The red/green runs above are real and can be re-run from the diff. If you would rather not take AI-assisted contributions here, say so and I will close this.

…ct_fields

When extract_fields is given a list of field names and the function
returns a TypedDict, a name that is not in the TypedDict was recorded as
an error and then looked up anyway, so users got a bare KeyError instead
of the error that lists the invalid fields.

Skip the lookup for unknown fields so the collected errors are raised.

Generated-by: Claude Code (Claude Opus 5.5)

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant