mastra-ai/mastra · error

ModelByInputTokens requires inputTokens for resolution

Error message

ModelByInputTokens requires inputTokens for resolution

What it means

ObservationalMemory can be configured with a ModelByInputTokens, which selects a concrete language model dynamically based on the size of the current input (token count). During resolution via getConcreteModel, the caller must supply the inputTokens count; without it there is no way to pick the right model tier, so the library throws instead of guessing. This is a programming error in the internal call path, surfacing when the token count was never computed or propagated.

Source

Thrown at packages/memory/src/processors/observational-memory/observational-memory.ts:761

  /**
   * Wait for any in-flight async buffering operations for the given thread/resource.
   * Used by server endpoints to block until buffering completes so the UI can get final state.
   */
  async waitForBuffering(
    threadId: string | null | undefined,
    resourceId: string | null | undefined,
    timeoutMs = 30000,
  ): Promise<void> {
    return BufferingCoordinator.awaitBuffering(threadId, resourceId, this.scope, timeoutMs);
  }

  private getConcreteModel(
    model: ObservationalMemoryModel,
    inputTokens?: number,
  ): Exclude<ObservationalMemoryModel, ModelByInputTokens> {
    if (model instanceof ModelByInputTokens) {
      if (inputTokens === undefined) {
        throw new Error('ModelByInputTokens requires inputTokens for resolution');
      }
      return model.resolve(inputTokens) as Exclude<ObservationalMemoryModel, ModelByInputTokens>;
    }

    return model as Exclude<ObservationalMemoryModel, ModelByInputTokens>;
  }

  private getModelToResolve(
    model: ObservationalMemoryModel,
    inputTokens?: number,
  ): Parameters<typeof resolveModelConfig>[0] {
    const concreteModel = this.getConcreteModel(model, inputTokens);

    if (Array.isArray(concreteModel)) {
      return (concreteModel[0]?.model ?? 'unknown') as Parameters<typeof resolveModelConfig>[0];
    }
    if (typeof concreteModel === 'function') {
      // Wrap to handle functions that may return ModelWithRetries[]

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Ensure the call is made on a thread/context that has messages so inputTokens can be computed before model resolution.
  2. If you call getConcreteModel yourself, always pass the computed inputTokens value.
  3. Replace ModelByInputTokens with a concrete static model if you don't need dynamic tiering — then resolution never needs inputTokens.
  4. Upgrade/check package version; if this occurs on normal empty-thread calls it may be a bug — file an issue with a reproduction.

Example fix

// before
const model = memory.getConcreteModel(new ModelByInputTokens({ small: m1, large: m2 }));
// after
const inputTokens = estimateTokens(messages);
const model = memory.getConcreteModel(new ModelByInputTokens({ small: m1, large: m2 }), inputTokens);
Defensive patterns

Strategy: validation

Validate before calling

if (model instanceof ModelByInputTokens) {
  const tokens = estimateInputTokens(thread.messages);
  if (tokens === undefined) throw new Error('Cannot resolve ModelByInputTokens: no token count available');
}

Type guard

function isResolvable(model: ObservationalMemoryModel, inputTokens?: number): boolean {
  return !(model instanceof ModelByInputTokens) || inputTokens !== undefined;
}

Prevention

When it happens

Trigger: getConcreteModel is called with a ModelByInputTokens instance and inputTokens === undefined. This happens when the internal concreteModel path resolves the model before any message/token counting has occurred (e.g. no stored messages, or a call path that skips token estimation), or if a custom subclass/caller invokes getConcreteModel without the second argument.

Common situations: Calling memory APIs (remember/recall) on an empty thread where no token usage has been recorded yet; custom code extending ObservationalMemory that calls getConcreteModel directly; a ModelByInputTokens configured without any messages in the thread so the resolver has no token count.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/9126159eb724b056. Report an issue: GitHub.