danny-avila/LibreChat · warning · Error

Subagent ${agentId} changed before it could be initialized.

Error message

Subagent ${agentId} changed before it could be initialized.

What it means

Thrown during lazy subagent initialization when the freshly fetched agent is missing or its current config id no longer matches the config id captured when the graph was planned. This is a TOCTOU (time-of-check/time-of-use) guard: the agent changed between planning and resolution.

Source

Thrown at api/server/services/Endpoints/agents/initialize.js:836

      }
      logger.error(`[initializeClient] Error loading subagent metadata ${agentId}:`, error);
      skippedAgentIds.add(agentId);
      return null;
    }
  };

  /**
   * Resolves the selected descriptor inside the foreground request. The
   * legacy initializer requires request/response objects for tool and MCP
   * setup, so this intentionally remains request-scoped until AI-1597 gives
   * child execution a durable runtime context.
   */
  const initializeLazySubagent = async ({ agentId, configId, context, lazyChildren }) => {
    throwIfAborted(context.signal);
    const agent = await waitForAbort(db.getAgentWithVersionCount({ id: agentId }), context.signal);
    throwIfAborted(context.signal);
    if (!agent || getLazySubagentConfigId(agent) !== configId) {
      throw new Error(`Subagent ${agentId} changed before it could be initialized.`);
    }
    if (!(await hasSubagentViewAccess(agent, agentId, context.signal))) {
      throw new Error(`You no longer have access to subagent ${agentId}.`);
    }
    const validation = await waitForAbort(
      validateAgentModel({ req, res, agent, modelsConfig, logViolation }),
      context.signal,
    );
    throwIfAborted(context.signal);
    if (!validation.isValid) {
      throw new Error(validation.error?.message ?? `Subagent ${agentId} failed model validation.`);
    }
    const scopedSkillIds = resolveAgentScopedSkillIds({
      agent,
      accessibleSkillIds,
      skillsCapabilityEnabled,
      ephemeralSkillsToggle,
    });

View on GitHub (pinned to 5ff282f900)

Solutions

  1. Retry the request after the concurrent edit/deletion settles.
  2. Avoid editing agents that are currently being initialized/invoked.
  3. Use stable agent versions/config ids for production graphs.
  4. Re-plan the subagent graph so it reflects the current agent definitions.
Defensive patterns

Strategy: retry

Validate before calling

const agent = await db.getAgentWithVersionCount({ id: agentId });
if (!agent || getLazySubagentConfigId(agent) !== configId) {
  throw new Error(`Agent ${agentId} changed; re-plan graph`);
}

Try / catch

try { await initializeLazySubagent({ agentId, configId, context }); }
catch (e) { if (/changed before it could be initialized/.test(e.message)) { await rePlanGraph(); return; } throw e; }

Prevention

When it happens

Trigger: The subagent's definition was edited, re-versioned, or deleted between graph planning and lazy initialization within the same request; an abort/version mismatch on getAgentWithVersionCount.

Common situations: Concurrent edits to an agent during a long-running request; versioned agents where the version bumped mid-request; deletion of a subagent referenced by an in-flight primary agent.

Related errors


AI-assisted analysis of danny-avila/LibreChat@5ff282f900 (2026-08-12). Data as JSON: /api/errors/5d50a0a69bcb33af. Report an issue: GitHub.