Skip to content

Exceptions inheriting from ValidationError raised in dec_hook implicitly wrapped in another ValidationError post 0.21.0 #1012

Description

@provinzkraut

Description

Pre 0.21.0, this would raise SomeError directly, now it raises msgspec.ValidationError with SomeError as a cause:

import msgspec

class SomeError(msgspec.ValidationError):
    pass

class Foo:
    pass

def dec_foo(tp, val):
    raise SomeError()

try:
    msgspec.convert("", type=Foo, dec_hook=dec_foo)
except Exception as exc:
    print(type(exc))

I believe this was an unintended side-effect of #790.

I'm not sure if this is desirable or not. It is however a breaking change

Activity

  1. provinzkraut commented on Apr 10, 2026

    @provinzkraut
    MemberAuthor

    I believe the issue is with the logic for how dec_hook errors are handled. According to the docs:

    Any TypeError or ValueError exceptions raised by this method will
    be considered "user facing" and converted into a ValidationError with
    additional context. All other exceptions will be raised directly.

    Since ValidationErrors are now also ValueErrors, they will get wrapped again. IMO we should add a guard there, that lets those bubble up unchanged as before, as raising a ValidationError is most likely intentional by the user.

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

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