dotnet/aspnetcore · error · Error

initialParameters must be an object, even if empty.

Error message

initialParameters must be an object, even if empty.

What it means

Thrown by RootComponentsFunctions.add when initialParameters is falsy. The dynamic root component API requires a parameters object (possibly empty {}) so that setParameters always receives a defined object; null/undefined is rejected.

Source

Thrown at src/Components/Web.JS/src/Rendering/JSRootComponents.ts:21

import { DotNet } from '@microsoft/dotnet-js-interop';

const pendingRootComponentContainerNamePrefix = '__bl-dynamic-root:';
const pendingRootComponentContainers = new Map<string, Element>();
let nextPendingDynamicRootComponentIdentifier = 0;

type ComponentParameters = object | null | undefined;

let manager: DotNet.DotNetObject | undefined;
let currentRendererId: number | undefined;
let jsComponentParametersByIdentifier: JSComponentParametersByIdentifier;
let hasInitializedJsComponents = false;

// These are the public APIs at Blazor.rootComponents.*
export const RootComponentsFunctions = {
  async add(toElement: Element, componentIdentifier: string, initialParameters: ComponentParameters): Promise<DynamicRootComponent> {
    if (!initialParameters) {
      throw new Error('initialParameters must be an object, even if empty.');
    }

    // Track the container so we can use it when the component gets attached to the document via a selector
    const containerIdentifier = pendingRootComponentContainerNamePrefix + (++nextPendingDynamicRootComponentIdentifier).toString();
    pendingRootComponentContainers.set(containerIdentifier, toElement);

    // Instruct .NET to add and render the new root component
    const componentId = await getRequiredManager().invokeMethodAsync<number>('AddRootComponent', componentIdentifier, containerIdentifier);
    const component = new DynamicRootComponent(componentId, jsComponentParametersByIdentifier[componentIdentifier]);
    await component.setParameters(initialParameters);
    return component;
  },
};

export function getAndRemovePendingRootComponentContainer(containerIdentifier: string): Element | undefined {
  const container = pendingRootComponentContainers.get(containerIdentifier);
  if (container) {
    pendingRootComponentContainers.delete(containerIdentifier);

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. Pass an empty object {} when the component takes no parameters.
  2. Default-coerce the argument: initialParameters ?? {} before calling add.

Example fix

// before
await Blazor.rootComponents.add(el, 'MyComponent', null);

// after
await Blazor.rootComponents.add(el, 'MyComponent', {});
Defensive patterns

Strategy: validation

Validate before calling

// Coerce to a guaranteed object before add.
const params = initialParameters ?? {};
await Blazor.rootComponents.add(el, 'MyComponent', params);

Type guard

function isParametersObject(v: unknown): v is object {
  return v !== null && typeof v === 'object';
}

Prevention

When it happens

Trigger: Calling Blazor.rootComponents.add(element, identifier, null) or omitting the third argument.

Common situations: Adding a component that legitimately has no parameters and passing null instead of {}; optional-parameter handling that resolves to undefined.

Related errors


AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06). Data as JSON: /api/errors/f7abcc2f79e9766e. Report an issue: GitHub.