Skip to content

GetParams() returns typed nil pointer wrapped in Params interface, causing nil check bypass and panic #1052

Description

@danny31-github

When a client sends a request without params (or with params: null) for methods flagged with missingParamsOK (e.g. notifications/initialized, ping, tools/list), the middleware receives a Params interface that passes a standard != nil check but panics on any method call.

Root cause:

In newServerMethodInfo, when unmarshalParams returns a nil interface (because params are missing and missingParamsOK allows it), newRequest leaves r.Params at its zero value — a typed nil pointer (e.g. (*InitializedParams)(nil)):

mi.newRequest = func(s Session, p Params, re *RequestExtra) Request {
    r := &ServerRequest[P]{Session: s.(*ServerSession), Extra: re}
    if p != nil {       // p is nil-interface here → skipped
        r.Params = p.(P)
    }
    return r            // r.Params is (*InitializedParams)(nil)
}

When GetParams() returns this typed nil pointer as a Params interface, the interface is non-nil (it carries type information), but calling any method on it (e.g. GetMeta()) dereferences a nil pointer and panics.

Our use case:

We have middleware that extracts _meta from every incoming request:

func metaFromRequest(req mcpsdk.Request) map[string]any {
    if params := req.GetParams(); params != nil {  // passes! interface is non-nil
        return params.GetMeta()                     // PANIC: nil pointer dereference
    }
    return nil
}

This crashes on notifications/initialized when the client sends no params.

Expected behavior:

GetParams() should return a nil Params interface (not a typed nil pointer) when params are absent, so that standard nil checks work correctly in middleware. Alternatively, GetParams() could use the existing orZero helper to unwrap typed nil pointers before returning.

Stack trace (v1.6.1):

github.com/modelcontextprotocol/go-sdk/mcp.(*InitializedParams).GetMeta(0x0?)
:1
Workaround:

Guard metaFromRequest with a method allowlist (only call for methods without missingParamsOK), or use reflect.ValueOf(params).IsNil() instead of params != nil.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions