{"record":{"id":"228fb228eb4496f3","repo":"denoland/deno","slug":"request-cache-mode-only-if-cached-can-only-be-us","errorCode":null,"errorMessage":"Request cache mode \"only-if-cached\" can only be used with same-origin mode","messagePattern":"Request cache mode \"only-if-cached\" can only be used with same-origin mode","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"ext/fetch/23_request.js","lineNumber":470,"sourceCode":"      request.mode = init.mode;\n    }\n\n    // 20. credentials\n    if (init.credentials !== undefined) {\n      request.credentialsMode = init.credentials;\n    }\n\n    // 21. cache\n    if (init.cache !== undefined) {\n      request.cacheMode = init.cache;\n    }\n\n    // If request's cache mode is \"only-if-cached\" and request's mode is not\n    // \"same-origin\", then throw a TypeError.\n    if (\n      request.cacheMode === \"only-if-cached\" && request.mode !== \"same-origin\"\n    ) {\n      throw new TypeError(\n        'Request cache mode \"only-if-cached\" can only be used with same-origin mode',\n      );\n    }\n\n    // 22.\n    if (init.redirect !== undefined) {\n      request.redirectMode = init.redirect;\n    }\n\n    // 23. integrity\n    if (init.integrity !== undefined) {\n      request.integrity = init.integrity;\n    }\n\n    // 24. keepalive\n    if (init.keepalive !== undefined) {\n      request.keepalive = init.keepalive;\n    }","sourceCodeStart":452,"sourceCodeEnd":488,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/ext/fetch/23_request.js#L452-L488","documentation":"Request constructor enforces the spec rule: cache mode 'only-if-cached' combined with any mode other than 'same-origin' throws TypeError. only-if-cached permits serving from the HTTP cache without network only for same-origin requests, so cross-origin (or default 'cors') usage is rejected.","triggerScenarios":"new Request(url, { cache: 'only-if-cached' }) with default mode 'cors'; fetch('https://cdn.example/x', { cache: 'only-if-cached' }) without mode: 'same-origin'.","commonSituations":"Offline-first code that adds cache: 'only-if-cached' to CDN or third-party URLs; copy-pasting a same-origin pattern onto cross-origin fetches.","solutions":["Add mode: 'same-origin' alongside cache: 'only-if-cached' when the URL is same-origin","For cross-origin URLs use cache: 'force-cache' (serves from cache when present, network otherwise) instead","Check URL origin against location.origin before selecting only-if-cached"],"exampleFix":"// before\nconst res = await fetch('https://same.example/api', {\n  cache: 'only-if-cached', // mode defaults to 'cors' -> throws\n});\n\n// after\nconst res = await fetch('https://same.example/api', {\n  cache: 'only-if-cached',\n  mode: 'same-origin',\n});","handlingStrategy":"type-guard","validationCode":"function cacheInit(url, cache) {\n  if (cache !== 'only-if-cached') return { cache };\n  const origin = typeof location !== 'undefined' ? location.origin : new URL(url, 'https://example.invalid').origin;\n  const target = new URL(url, typeof location !== 'undefined' ? location.href : undefined).origin;\n  if (origin !== target) return { cache: 'force-cache' }; // cross-origin fallback\n  return { cache, mode: 'same-origin' };\n}","typeGuard":"const canUseOnlyIfCached = (url) => {\n  try {\n    return typeof location === 'undefined' || new URL(url, location.href).origin === location.origin;\n  } catch {\n    return false;\n  }\n};","tryCatchPattern":null,"preventionTips":["Pair cache: 'only-if-cached' with mode: 'same-origin' by construction","Use 'force-cache' for cross-origin offline behavior","Add a helper that picks the cache mode based on URL origin"],"tags":["fetch","request","cache","cors"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}