musistudio/claude-code-router · warning

[plugin-marketplace] Cached module is missing while offline:

Error message

[plugin-marketplace] Cached module is missing while offline: ${moduleUrl}

What it means

The plugin marketplace resolver was asked for a module while in offline mode, and the module is not present in the local cache (or exists but its URL-keyed cache entry doesn't match). It warns and returns undefined, so the module cannot be loaded until connectivity returns or the module is cached.

Source

Thrown at packages/core/src/plugins/marketplace.ts:254

    throw new Error(`Marketplace module must be an HTTPS URL: ${moduleUrl}`);
  }

  const extension = path.extname(url.pathname).toLowerCase();
  if (![".cjs", ".js", ".mjs"].includes(extension)) {
    throw new Error(`Marketplace module must be a JavaScript file: ${moduleUrl}`);
  }

  const expectedSha256 = normalizeSha256Integrity(integrity);
  const cacheKey = expectedSha256 || hashString(moduleUrl);
  const file = path.join(marketplaceModuleCacheDir, `${sanitizeFileSegment(id)}-${cacheKey.slice(0, 24)}${extension}`);
  if (existsSync(file) && (options.offline || expectedSha256)) {
    if (expectedSha256) {
      verifySha256(readFileSync(file, "utf8"), expectedSha256, moduleUrl);
    }
    return file;
  }
  if (options.offline) {
    console.warn(`[plugin-marketplace] Cached module is missing while offline: ${moduleUrl}`);
    return undefined;
  }

  const source = await fetchText(moduleUrl, maxMarketplaceModuleBytes);
  if (expectedSha256) {
    verifySha256(source, expectedSha256, moduleUrl);
  }
  ensureMarketplaceCacheDir();
  writeFileSync(file, source, "utf8");
  return file;
}

async function fetchText(url: string, maxBytes: number): Promise<string> {
  assertHttpsUrl(url, "Marketplace URL");
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), marketplaceFetchTimeoutMs);
  try {
    const response = await fetchWithSystemProxy(url, {

View on GitHub (pinned to 99f24806c6)

Solutions

  1. Run once online (offline=false) to populate the cache, then rerun offline
  2. Pre-populate the cache in CI by downloading marketplace modules in a network-enabled step before the offline step
  3. Verify the cache directory is persistent (not a tmpfs/ephemeral container layer) across runs
  4. Confirm the moduleUrl matches the one used when the cache was primed

Example fix

# before (CI job)
opencode --offline   # cache empty -> warning

# after
cache-step:
  opencode plugins prefetch https://example.com/module.js  # network enabled
run-step:
  opencode --offline
Defensive patterns

Strategy: validation

Validate before calling

const cached = await marketplace.cachedModulePath(url, { offline: true });
if (!cached) throw new Error(`Module ${url} not cached — prime the cache while online first`);

Prevention

When it happens

Trigger: Running with options.offline=true and requesting a marketplace module URL never previously downloaded; cache cleared (or cache keyed by URL/hash changed); expected sha256 mismatch causing cache invalidation in offline runs.

Common situations: CI or air-gapped environments with offline=true but cache priming step skipped; cache directory wiped between runs; pinned module URL changed so the cache key misses.

Related errors


AI-assisted analysis of musistudio/claude-code-router@99f24806c6 (2026-08-27). Data as JSON: /api/errors/6aee7ae774daa1b2. Report an issue: GitHub.