danny-avila/LibreChat · error · Error

No plugin auth ${authField} found for user ${userId}${plugin

Error message

No plugin auth ${authField} found for user ${userId}${pluginInfo}

What it means

Thrown by PluginService.getUserPluginAuthValue when findOnePluginAuth({ userId, authField, [pluginKey] }) returns null — i.e. the user has no stored, encrypted credential for that auth field. The function exists to decrypt per-user plugin secrets (API keys, OAuth tokens), so a missing record means the plugin cannot authenticate on that user's behalf. When called with throwError=false the error is swallowed and null is returned instead.

Source

Thrown at api/server/services/PluginService.js:45

 *   console.log(value);
 * }).catch(err => {
 *   console.error(err);
 * });
 *
 * @throws {Error} Throws an error if there's an issue during the retrieval or decryption process, or if the authentication value does not exist.
 * @async
 */
const getUserPluginAuthValue = async (userId, authField, throwError = true, pluginKey) => {
  try {
    const searchParams = { userId, authField };
    if (pluginKey) {
      searchParams.pluginKey = pluginKey;
    }

    const pluginAuth = await findOnePluginAuth(searchParams);
    if (!pluginAuth) {
      const pluginInfo = pluginKey ? ` for plugin ${pluginKey}` : '';
      throw new Error(`No plugin auth ${authField} found for user ${userId}${pluginInfo}`);
    }

    const decryptedValue = await decrypt(pluginAuth.value);
    return decryptedValue;
  } catch (err) {
    if (!throwError) {
      return null;
    }
    logger.error('[getUserPluginAuthValue]', err);
    throw err;
  }
};

// const updateUserPluginAuth = async (userId, authField, pluginKey, value) => {
//   try {
//     const encryptedValue = encrypt(value);

//     const pluginAuth = await PluginAuth.findOneAndUpdate(

View on GitHub (pinned to 5ff282f900)

Solutions

  1. Pass throwError=false at call sites where the credential is optional, and handle the null return.
  2. Verify the exact authField string matches what was written during plugin setup (check the plugin's auth schema/config).
  3. Ensure the user has completed authentication for the plugin (re-trigger OAuth or re-prompt for the API key).
  4. Confirm pluginKey, when supplied, matches the stored record's pluginKey exactly.

Example fix

// before
const key = await getUserPluginAuthValue(userId, 'API_KEY', true, pluginKey);

// after
const key = await getUserPluginAuthValue(userId, 'API_KEY', false, pluginKey);
if (!key) {
  return { error: 'Plugin not configured. Please connect your account.' };
}
Defensive patterns

Strategy: try-catch

Validate before calling

const value = await getUserPluginAuthValue(userId, authField, false, pluginKey);
if (!value) {
  return { configured: false };
}

Type guard

const isPluginAuthAvailable = async (userId, authField, pluginKey) =>
  !!(await findOnePluginAuth(pluginKey ? { userId, authField, pluginKey } : { userId, authField }));

Try / catch

try {
  return await getUserPluginAuthValue(userId, authField, true, pluginKey);
} catch (err) {
  if (err.message.startsWith('No plugin auth ')) {
    return null; // or prompt the user to configure the plugin
  }
  throw err;
}

Prevention

When it happens

Trigger: Invoking a plugin/MCP tool before the user has completed the OAuth flow or entered their API key; referencing the wrong authField name (e.g. 'APIKEY' vs 'API_KEY'); passing a pluginKey that does not match the key under which the credential was stored; a different user id type (string vs ObjectId) in the query.

Common situations: Plugin re-keyed after an update so the stored authField name changed; user cleared their stored credentials; multi-tenant setup where userId namespace differs; calling getUserPluginAuthValue with the third positional arg accidentally set to true when the value is optional.

Related errors


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