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

Cache query options control which URL search parameters participate in the cache key: include is an allowlist, exclude a blocklist. normalizeQueryConfig throws CacheQueryConfigConflict when both are set, because combining them would make the effective key ambiguous.

Solutions

  1. Keep exactly one of query.include or query.exclude.
  2. Prefer include for an explicit allowlist — every parameter not listed is ignored automatically.
  3. Delete the exclude patterns; with include set they are redundant by design.

Example fix

// before
Astro.cache.set({
  query: { include: ['page'], exclude: ['utm_source', 'ref'] },
});

// after
Astro.cache.set({
  query: { include: ['page'] },
});
Defensive patterns

Strategy: validation

Validate before calling

// Validate cache hints before applying them
function assertCacheQuery(query: { include?: string[]; exclude?: string[] } = {}) {
  if (query.include && query.exclude) {
    throw new Error('cache query: use only one of include or exclude');
  }
}
assertCacheQuery(hint.query);
Astro.cache.set(hint);

Type guard

const isValidCacheQuery = (q?: { include?: string[]; exclude?: string[] }): boolean =>
  !(q?.include && q?.exclude);

Prevention

When it happens

Trigger: Passing { query: { include: ['page'], exclude: ['utm_*'] } } in a cache hint — for example Astro.cache.set(), route cache options, or a middleware setting cacheHint on the response.

Common situations: Merging copied config fragments from docs and examples; iterating on cache-key tuning and forgetting to remove one side; converting an exclude list to an allowlist without deleting the old key.

Related errors


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

Appendix: source

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

	'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 e294953aa8)