What does HRESULT 0x80020010 (DISP_E_BADCALLEE) mean?

 
Previous Next
DISP_E_PARAMNOTOPTIONAL DISP_E_NOTACOLLECTION

DISP_E_BADCALLEE

Automation callee violated the dispatch contract

DISP_E_BADCALLEE is HRESULT 2147614736 (0x80020010) from winerror.h. AllStat describes it as “Invalid callee.” The value must be interpreted at IDispatch::Invoke after control transfers to a target implementation, because the same high-level symptom can come from a different contract boundary and require different cleanup.

The decisive interpretation for DISP_E_BADCALLEE is that the target object behaved inconsistently with the Automation calling convention or returned malformed call data. For reliable triage of DISP_E_BADCALLEE, store the native HRESULT and symbolic identity before generic error handling rewrites either one.

Where the result appears

  • DISP_E_BADCALLEE is returned while Automation binds or executes IDispatch::Invoke after control transfers to a target implementation.
  • For DISP_E_BADCALLEE, retain the member name and DISPID, invocation flags, LCID, cArgs, cNamedArgs, and the exact VARIANTARG sequence in reverse Automation order.
  • The output contract for DISP_E_BADCALLEE includes puArgErr, EXCEPINFO, result VARIANT, by-reference values, and SAFEARRAY lock or ownership state; inspect them before cleanup.

The root-cause boundary for DISP_E_BADCALLEE is the component that returned it, not the application screen on which the result was eventually displayed.

Typical causes and interpretation boundary

Common cause categories for DISP_E_BADCALLEE are: a custom IDispatch implementation corrupts DISPPARAMS; output VARIANT is invalid; exception translation breaks ABI; proxy and server disagree. Investigate DISP_E_BADCALLEE through falsifiable cause hypotheses and keep the first lower-level failure that explains the observed HRESULT.

The check that separates DISP_E_BADCALLEE from nearby HRESULTs is: the target object behaved inconsistently with the Automation calling convention or returned malformed call data. Use the decisive condition for DISP_E_BADCALLEE as a test assertion; if it cannot be asserted, diagnosis is not complete.

Evidence and telemetry

  • Record DISP_E_BADCALLEE with the object CLSID or ProgID, interface identity, member DISPID, dispatch flags, and type-library version.
  • For DISP_E_BADCALLEE, capture callee CLSID and version; DISPID; EXCEPINFO; output VARIANT; stack and marshaling diagnostics; proxy/stub versions.
  • Log VARIANT type tags, dimensions, bounds, lengths, and null/empty distinctions for DISP_E_BADCALLEE, but redact actual confidential argument values.
  • Preserve the caller language/runtime, generated interop version, LCID, and whether the call crossed a process boundary when DISP_E_BADCALLEE occurs.
  • After DISP_E_BADCALLEE, call VariantClear, SysFreeString, SafeArrayDestroy, or release interfaces only for values whose ownership was transferred by the documented contract.

Logs for DISP_E_BADCALLEE should expose enough structure to reproduce the failure without becoming a secondary store of sensitive input data.

Diagnostic sequence

  • Capture DISP_E_BADCALLEE (0x80020010) at IDispatch::GetIDsOfNames or IDispatch::Invoke before the language runtime converts it to a script exception.
  • For <code>DISP_E_BADCALLEE</code>, resolve the deployed member signature from ITypeInfo and compare its DISPIDs, parameter flags, VARTYPEs, optional values, and property-put rules with the caller.
  • Prove the decisive condition for DISP_E_BADCALLEE: the target object behaved inconsistently with the Automation calling convention or returned malformed call data.
  • Inspect the likely binding or representation causes for DISP_E_BADCALLEE: a custom IDispatch implementation corrupts DISPPARAMS; output VARIANT is invalid; exception translation breaks ABI; proxy and server disagree.
  • Reconstruct DISPPARAMS exactly, including reverse positional ordering and named argument placement, then reproduce DISP_E_BADCALLEE with the smallest value set.
  • Verify the result VARIANT, EXCEPINFO, puArgErr, by-reference arguments, SAFEARRAY lock count, and object state after DISP_E_BADCALLEE before deciding on retry.

Correct handling and recovery

For DISP_E_BADCALLEE, the appropriate recovery is to isolate the faulty component, validate its IDispatch implementation and output ownership, and do not hide the defect with broad argument retries. Do not loop on DISP_E_BADCALLEE; retry only under a documented transient condition with bounded delay and post-operation reconciliation.

After observing DISP_E_BADCALLEE, separate local resource cleanup from server-side reconciliation and perform each only for the failing activity ID.

Practical scenario

A custom server writes a BSTR pointer without setting the result VARTYPE; correcting the implementation resolves the callee failure.

The acceptance test for DISP_E_BADCALLEE should prove that the proposed repair changes the predicted contract fact rather than merely hiding the message.

Difference from related HRESULTs

DISP_E_EXCEPTION is a valid application exception returned through Automation; DISP_E_BADCALLEE indicates the callee contract itself is broken.

Preserve the neighboring-result distinction for DISP_E_BADCALLEE in metrics and incident reports to avoid applying the wrong remediation.

Developer and administrator guidance

Automation adapters should handle DISP_E_BADCALLEE at the dispatch boundary and expose the member, parameter, and type information needed to repair the call. A generic retry after <code>DISP_E_BADCALLEE</code> with unchanged DISPPARAMS usually repeats the same deterministic binding error.

For DISP_E_BADCALLEE, deployment owners should compare the registered type library and server binary as one versioned unit. After <code>DISP_E_BADCALLEE</code>, re-registering arbitrary DLLs or changing locale system-wide is inappropriate unless the captured metadata proves registration or LCID drift.

References


Looking for a different code? Search another status or error code.