Mintplex-Labs/anything-llm · warning · Error

This agent invocation is already closed

Error message

This agent invocation is already closed

What it means

Thrown by #validInvocation() (server/utils/agents/index.js:539) during agent.init() when the WorkspaceAgentInvocation record for the invocation UUID has closed === true. The guard prevents starting an agent session against an invocation that was already ended (closed by the user, timed out, or previously completed).

Source

Thrown at server/utils/agents/index.js:544

      },
      { user, thread }
    );

    this.provider = router.resolvedRoute.provider;
    this.model = router.resolvedRoute.model;
    this.routingMetadata = router.routingMetadata;
    // Held so the model-router-cooldown plugin can restart the cooldown when
    // the agent stops responding. Routing re-resolves per turn, so this always
    // points at the router for the current route.
    this._modelRouter = router;
  }

  async #validInvocation() {
    const invocation = await WorkspaceAgentInvocation.getWithWorkspace({
      uuid: String(this.#invocationUUID),
    });
    if (invocation?.closed)
      throw new Error("This agent invocation is already closed");
    this.invocation = invocation ?? null;
  }

  parseCallOptions(args, config = {}, pluginName) {
    const callOpts = {};
    for (const [param, definition] of Object.entries(config)) {
      if (
        definition.required &&
        (!Object.prototype.hasOwnProperty.call(args, param) ||
          args[param] === null)
      ) {
        this.log(
          `'${param}' required parameter for '${pluginName}' plugin is missing. Plugin may not function or crash agent.`
        );
        continue;
      }
      callOpts[param] = Object.prototype.hasOwnProperty.call(args, param)
        ? args[param]

View on GitHub (pinned to 526360e320)

Solutions

  1. Have the client open a new agent invocation instead of reusing the closed UUID.
  2. If unexpected, inspect why the row is closed (WorkspaceAgentInvocation.closed) and ensure no code path closes it prematurely.
  3. Add idempotency: ignore re-init on closed invocations rather than throwing.

Example fix

// before
const agent = new AgentHandler({ uuid });
await agent.init();
// after
const inv = await WorkspaceAgentInvocation.getWithWorkspace({ uuid });
if (inv?.closed) return startNewInvocation();
const agent = new AgentHandler({ uuid });
await agent.init();
Defensive patterns

Strategy: validation

Validate before calling

const inv = await WorkspaceAgentInvocation.getWithWorkspace({ uuid: String(uuid) });
if (inv?.closed) return openFreshInvocation();

Try / catch

try { await agent.init(); } catch (e) { if (/already closed/.test(e.message)) return startNewAgentSession(); throw e; }

Prevention

When it happens

Trigger: agent.init() is called for an invocation UUID whose DB row is closed - e.g. a replayed request, a duplicate webhook, a UI that re-triggers a finished agent thread, or an invocation closed between dispatch and init().

Common situations: User closed the agent chat and an in-flight request retried; background job replayed; concurrent duplicate submissions; invocation closed by another tab.

Related errors


AI-assisted analysis of Mintplex-Labs/anything-llm@526360e320 (2026-08-13). Data as JSON: /api/errors/c12cf0b824273318. Report an issue: GitHub.