{"record":{"id":"4fba81819f079a4e","repo":"denoland/deno","slug":"deno-autoupdate-no-patch-available-for","errorCode":null,"errorMessage":"Deno.autoUpdate: no patch available for","messagePattern":"Deno\\.autoUpdate: no patch available for","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cli/rt/desktop.rs","lineNumber":1151,"sourceCode":"            return;\n          }}\n          if (!op_desktop_verify_ed25519(publicKey, sig, te.encode(signed))) {{\n            console.error(\"Deno.autoUpdate: manifest signature verification failed\");\n            return;\n          }}\n          // Re-parse the signed payload — only its contents are trusted.\n          try {{\n            manifest = JSON.parse(signed);\n          }} catch {{\n            console.error(\"Deno.autoUpdate: signed payload is not valid JSON\");\n            return;\n          }}\n          if (manifest.version === _version) return;\n        }}\n\n        const patchEntry = manifest.patches?.[_version];\n        if (!patchEntry) {{\n          console.warn(\"Deno.autoUpdate: no patch available for\",\n            _version, \"->\", manifest.version);\n          return;\n        }}\n        // Accept either a string (legacy/unsafe) or {{ name, sha256 }}. The\n        // SHA-256 is required — Rust will reject the patch otherwise.\n        const patchName = typeof patchEntry === \"string\"\n          ? patchEntry\n          : patchEntry?.name;\n        const patchSha256 = typeof patchEntry === \"object\"\n          ? patchEntry?.sha256\n          : undefined;\n        if (!patchName) {{\n          console.error(\"Deno.autoUpdate: malformed patch entry\");\n          return;\n        }}\n        if (typeof patchSha256 !== \"string\" || patchSha256.length !== 64) {{\n          console.error(\n            \"Deno.autoUpdate: manifest patch entry must include sha256\",","sourceCodeStart":1133,"sourceCodeEnd":1169,"githubUrl":"https://github.com/denoland/deno/blob/f7822238cab635a3a19f99f493f675fa81a7f9d8/cli/rt/desktop.rs#L1133-L1169","documentation":"The update manifest was fetched and parsed, its version differs from the running Deno.desktopVersion, but manifest.patches has no entry keyed by the current version (cli/rt/desktop.rs:1078-1083). The delta-update model requires a patch for every source version, so the runtime cannot update and warns, logging both versions. The app remains on its current version.","triggerScenarios":"Publishing release 1.2.0 with patches only from 1.1.0 while users run 1.0.0; a patches map keyed with a different version format than the baked-in _version (e.g., 'v1.0.0' vs '1.0.0'); a publish pipeline that only generates a patch from the immediately previous release; with publicKey configured, the signed payload re-parsed from manifest.signed lacking the patches entry.","commonSituations":"Users on old skipped versions after several rapid releases; release scripts that forget to backfill patches for still-supported versions; version-string mismatches between deno.json and the manifest keys.","solutions":["Add a patches entry keyed by the exact running version, e.g. patches['1.0.0'] = { name, sha256 }, and republish latest.json","If you do not intend to delta-patch old versions, tell those users to reinstall the latest full build so no patch is needed","Compare Deno.desktopVersion (printed in the warning) against the patches keys character-by-character to catch formatting mismatches","If using signed manifests, ensure the signed payload itself contains the patches map, since only its contents are trusted"],"exampleFix":"// before: user on 1.0.0, manifest only patches 1.1.0\n{\"version\":\"1.2.0\",\"patches\":{\"1.1.0\":{\"name\":\"p-1.1.0.bin\",\"sha256\":\"aa...\"}}}\n\n// after: backfill an entry for every supported source version\n{\"version\":\"1.2.0\",\"patches\":{\n  \"1.0.0\":{\"name\":\"p-1.0.0.bin\",\"sha256\":\"bb...\"},\n  \"1.1.0\":{\"name\":\"p-1.1.0.bin\",\"sha256\":\"aa...\"}\n}}","handlingStrategy":"validation","validationCode":"// release-time check: every supported source version must have a valid patch entry\nconst manifest = JSON.parse(await Deno.readText(\"latest.json\"));\nconst supported = [\"1.0.0\", \"1.1.0\"]; // versions still in the field\nfor (const v of supported) {\n  const e = manifest.patches?.[v];\n  if (!e?.name || typeof e.sha256 !== \"string\" || e.sha256.length !== 64) {\n    throw new Error(`latest.json: missing/invalid patch entry for ${v}`);\n  }\n}","typeGuard":"function hasPatchFor(m: unknown, version: string): m is { patches: Record<string, { name: string; sha256: string }> } {\n  const p = (m as { patches?: Record<string, unknown> })?.patches;\n  const e = p?.[version] as { name?: unknown; sha256?: unknown } | undefined;\n  return !!e && typeof e.name === \"string\" && typeof e.sha256 === \"string\" && e.sha256.length === 64;\n}","tryCatchPattern":null,"preventionTips":["Generate patches from every still-supported version at release time","Assert patch coverage in CI so a missing entry blocks the release","Treat 'no patch available' logs from real users as a signal to backfill patches","Keep version strings (deno.json vs manifest keys) in one canonical format"],"tags":["desktop","auto-update","patch","manifest","version-mismatch"],"backgroundTag":"missing-manifest-entry","analyzedSha":"f7822238cab635a3a19f99f493f675fa81a7f9d8","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T04:17:50.494Z"}