Skip to content

[BUG] Head.build raises TypeError: 'NoneType' object is not callable when body lacks output_size #811

@shaun0927

Description

@shaun0927

Bug description

PR #802 (commit ab7207cf, "Sec pic fix") changed the default sentinel in transformers4rec/torch/model/base.py from lambda: None to None:

if not getattr(self.body, "output_size", None)():

if not getattr(self.body, "output_size", None)():
    raise ValueError(
        "Can't infer output-size of the body, please provide  "
        "a `Block` with a output-size. You can wrap any torch.Module in a Block."
    )

When self.body does not have an output_size attribute, getattr(..., None) returns None, and the trailing () then evaluates None(), which raises TypeError: 'NoneType' object is not callable.

The original lambda: None sentinel was callable and returned a falsy value, so the intended raise ValueError(...) path below was actually reached. The current code path short-circuits with the wrong exception type, making the error message unactionable.

This is not caught by tests because all fixtures provide bodies with output_size.

Steps/Code to reproduce bug

class Body:
    pass

body = Body()
getattr(body, "output_size", None)()
# TypeError: 'NoneType' object is not callable

Versus the pre-#802 behavior:

getattr(body, "output_size", lambda: None)()
# None   (falsy, falls through to `raise ValueError(...)` in Head.build)

Expected behavior

When the body lacks output_size, Head.build should raise the original ValueError("Can't infer output-size of the body ...") so the user gets a clear, actionable message.

Environment details

  • Transformers4Rec: main @ 8bf122f5 (regression introduced by PR Sec pic fix #802 / commit ab7207cf)
  • Python: any

Additional context

Two equivalent minimal fixes:

Option A — restore the callable sentinel:

if not getattr(self.body, "output_size", lambda: None)():

Option B — explicit two-step check (slightly more readable):

output_size_fn = getattr(self.body, "output_size", None)
if output_size_fn is None or not output_size_fn():
    raise ValueError(...)

Option A preserves behavior byte-for-byte. Happy to send a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions