danny-avila/LibreChat · error · Error

GitHub skill sync runner is not configured

Error message

GitHub skill sync runner is not configured

What it means

createAdminSkillsSyncHandlers builds a getRunner helper that resolves the GitHubSkillSyncRunner from deps.getRunner(req) or deps.runner. If neither is supplied when the handlers were constructed, every sync endpoint (status, run, setCredential, deleteCredential) throws this error on the first call. The runner is the component that actually performs GitHub skill repository sync.

Source

Thrown at packages/api/src/admin/skills.ts:362

    }
  };

  return {
    attachBaseSkillSyncConfig,
    attachCredentialReadAccess,
    requireReadSkills: requireSkillCapability(SystemCapabilities.READ_SKILLS),
    requirePlatformManageSkills: requireSkillCapability(SystemCapabilities.MANAGE_SKILLS, {
      platformOnly: true,
    }),
    requireSyncRunCapability,
  };
}

export function createAdminSkillsSyncHandlers(deps: AdminSkillSyncDeps): AdminSkillsSyncHandlers {
  function getRunner(req: Request): GitHubSkillSyncRunner {
    const runner = deps.getRunner?.(req) ?? deps.runner;
    if (!runner) {
      throw new Error('GitHub skill sync runner is not configured');
    }
    return runner;
  }

  async function getSyncStatus(req: AdminSkillsRequest, res: Response) {
    const includeCredentialMetadata = req.skillSyncCanReadCredentials !== false;
    const status = await getRunner(req).getStatus();
    const response: TGitHubSkillSyncStatusResponse = {
      enabled: status.enabled,
      intervalMinutes: status.intervalMinutes,
      runOnStartup: status.runOnStartup,
      sources: getVisibleSourceStatuses(req, status.sources).map((source) =>
        serializeSourceStatus(source, { includeCredentialMetadata }),
      ),
      credentials: includeCredentialMetadata ? status.credentials.map(serializeCredential) : [],
      fineGrainedTokenRecommendation: status.fineGrainedTokenRecommendation,
    };
    return res.status(200).json(response);

View on GitHub (pinned to 5ff282f900)

Solutions

  1. Provide a runner (or a getRunner factory) when calling createAdminSkillsSyncHandlers.
  2. If the feature is intentionally disabled, do not mount the sync routes — return 501/503 from the router instead of letting handlers throw.
  3. For multi-tenant setups, ensure getRunner returns a runner for every tenant or returns a clear 404.

Example fix

// before
const handlers = createAdminSkillsSyncHandlers({} as AdminSkillSyncDeps); // no runner

// after
const runner = createGitHubSkillSyncRunner({ sources, tokenStore });
const handlers = createAdminSkillsSyncHandlers({ runner });
Defensive patterns

Strategy: validation

Validate before calling

// before constructing handlers, confirm a runner is available
function ensureRunner(deps: AdminSkillSyncDeps): void {
  if (!deps.runner && typeof deps.getRunner !== 'function') {
    throw new Error('Cannot mount skill sync routes without a GitHubSkillSyncRunner');
  }
}

Type guard

const hasRunner = (d: AdminSkillSyncDeps): boolean =>
  Boolean(d.runner) || typeof d.getRunner === 'function';

Try / catch

router.get('/sync/status', async (req, res) => {
  try {
    await handlers.getSyncStatus(req, res);
  } catch (error) {
    if (error instanceof Error && error.message.includes('not configured')) {
      return res.status(503).json({ error: 'Skill sync is not configured' });
    }
    throw error;
  }
});

Prevention

When it happens

Trigger: Calling any admin skill-sync endpoint when the server was started without wiring a GitHubSkillSyncRunner into createAdminSkillsSyncHandlers' deps; feature flag for skill sync disabled but routes still mounted; misconfigured DI where getRunner returns undefined for the current tenant.

Common situations: Skill-sync feature turned off by config but routes exposed; a tenant/multi-tenant deployment where the runner factory returns undefined for some tenants; deploying without setting the GitHub skill sync env vars (token, sources).

Related errors


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