Ad Space — Top Banner

EInvalidCast

Delphi Programming Language

Severity: Moderate

What Does This Error Mean?

EInvalidCast is raised when you try to cast an object to a class it does not actually belong to. For example, writing TButton(SomeControl) when SomeControl is actually a TLabel will raise this exception. Use the safe as operator or check with is before casting.

Affected Models

  • Delphi 10.4 Sydney
  • Delphi 11 Alexandria
  • Delphi 12 Athens
  • Embarcadero RAD Studio
  • Free Pascal / Lazarus

Common Causes

  • Hard-casting an object variable to the wrong class using TFoo(obj) syntax
  • Iterating over a component list and casting every item to a specific type without checking
  • Receiving an object through a TObject parameter and assuming its type without verification
  • Casting interface references to the wrong interface type
  • Deserializing objects from a stream and using the wrong class for the cast

How to Fix It

  1. Run the program in the debugger. When EInvalidCast fires, look at the call stack and the variable involved. Check what class the object actually is versus what class you tried to cast it to.

    In the debugger, hover over the object variable — it will show the actual runtime type in the tooltip.

  2. Replace hard casts (TFoo(obj)) with the safe as operator: MyFoo := obj as TFoo. The as operator performs the same cast but raises EInvalidCast with a descriptive message instead of causing silent memory corruption.

    Hard casts (TFoo(obj)) never raise EInvalidCast — they bypass the check entirely. EInvalidCast is specifically raised by the as operator.

  3. Before casting, use the is operator to verify the type: if obj is TFoo then MyFoo := TFoo(obj). This is the safest pattern — check first, then cast.

    After a successful is check, the hard cast TFoo(obj) is safe because you have already confirmed the type.

  4. When iterating over component lists (like a form's Components array), always check the type before casting: for I := 0 to ComponentCount - 1 do if Components[I] is TEdit then TEdit(Components[I]).Clear;

    Component arrays can contain many different types mixed together — never assume all entries are the same type.

  5. Review any code that casts objects received from external sources (streams, plugins, interfaces). Validate the type at the boundary before using it.

    Objects coming from outside your direct control are the most common source of unexpected types.

When to Call a Professional

EInvalidCast always means the code assumed an object was a type that it is not. Audit every hard cast in the code path that leads to the exception. Replacing TFoo(obj) with obj as TFoo raises the exception with a clearer message, and using is before casting prevents it entirely.

Frequently Asked Questions

Why does TFoo(obj) not raise EInvalidCast but obj as TFoo does?

TFoo(obj) is an unsafe hard cast — it tells the compiler to treat the memory as TFoo without any runtime check. This can cause silent data corruption or an access violation later. The as operator performs a runtime type check using RTTI and raises EInvalidCast if the type does not match — making the error visible immediately.

Can I catch EInvalidCast and continue safely?

You can catch it, but if EInvalidCast is raised the operation you intended has not happened. You should log the error and skip the problematic item rather than trying to continue with an invalid object. The real fix is to prevent the wrong type from reaching the cast in the first place using is checks.

Is EInvalidCast related to variant type mismatches?

No. Variant type mismatches raise EVariantTypeCastError, not EInvalidCast. EInvalidCast is specific to object and interface typecasts using the as operator. Both indicate type mismatch problems but in different areas of the Delphi type system.