withastro/astro · error · AstroError

CacheQueryConfigConflict

CacheQueryConfigConflict

Error message

`query.include` and `query.exclude` cannot be used together. Use `include` to allowlist specific parameters, or `exclude` to blocklist them.

What it means

The memory cache's query-key normalization refuses to accept both an `include` allowlist and an `exclude` blocklist at the same time, because their semantics are contradictory (include restricts to a set; exclude removes from all). Allowing both would leave the actual cache-key behavior ambiguous. Astro throws this during config normalization so the intent is unambiguous at startup.

Source

Thrown at packages/astro/src/core/cache/memory-provider.ts:153

	'oly_enc_id',
	'rb_clickid',
	's_cid',
	'vero_id',
	'wickedid',
	'yclid',
	'__s',
	'ref',
];

interface NormalizedQueryConfig {
	sort: boolean;
	include: string[] | null;
	excludeMatcher: picomatch.Matcher | null;
}

function normalizeQueryConfig(query: MemoryCacheQueryOptions | undefined): NormalizedQueryConfig {
	if (query?.include && query?.exclude) {
		throw new AstroError(CacheQueryConfigConflict);
	}

	const sort = query?.sort !== false;
	const include = query?.include ?? null;

	// When `include` is set, exclude is irrelevant — only the allowlisted params matter.
	const excludePatterns = include ? [] : (query?.exclude ?? DEFAULT_EXCLUDED_PARAMS);
	const excludeMatcher =
		excludePatterns.length > 0 ? picomatch(excludePatterns, { nocase: true }) : null;
	return { sort, include, excludeMatcher };
}

/**
 * Build the query string portion of a cache key, applying sorting and filtering.
 */
function buildQueryString(url: URL, config: NormalizedQueryConfig): string {
	const params = new URLSearchParams(url.searchParams);

View on GitHub (pinned to d081033d5f)

Solutions

  1. Pick one strategy: keep `query.include` and delete `query.exclude` (allowlist), or keep `query.exclude` and delete `query.include` (blocklist).
  2. If you need allowlist semantics with a few exclusions, note that `include` already ignores everything not listed, so exclusions are redundant — use only `include`.
  3. If you want default tracking-param exclusion plus your own blocklist, omit `include` and pass only `exclude` (it replaces the defaults).

Example fix

// before
import { memoryCache } from 'astro/cache/memory';
memoryCache({ query: { include: ['page', 'q'], exclude: ['utm_*'] } });

// after
import { memoryCache } from 'astro/cache/memory';
memoryCache({ query: { include: ['page', 'q'] } });
Defensive patterns

Strategy: validation

Validate before calling

function assertCacheQuery(q) {
  if (q && q.include && q.exclude) {
    throw new Error('Pass only one of query.include or query.exclude to memoryCache().');
  }
}

Type guard

function isSingleStrategyQuery(q) {
  return !(q && q.include && q.exclude);
}

Prevention

When it happens

Trigger: Calling `memoryCache({ query: { include: ['page'], exclude: ['utm_*'] } })` — passing both `query.include` and `query.exclude` as non-empty values to the `memoryCache` provider factory. The check fires in `normalizeQueryConfig` the moment `query?.include && query?.exclude` are both truthy.

Common situations: Copying an `exclude` snippet from docs and then adding an `include` list; migrating from a blocklist strategy to an allowlist without removing the old `exclude` key; merging two cache config objects where one supplies `include` and the other supplies `exclude`.

Related errors


AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12). Data as JSON: /api/errors/83edcd5912ddc56e. Report an issue: GitHub.