{"record":{"id":"04eff6eb909651c1","repo":"gatsbyjs/gatsby","slug":"could-not-find-matching-operation-for-requestedp","errorCode":null,"errorMessage":"Could not find matching operation for ${requestedPathOnDisk}","messagePattern":"Could not find matching operation for (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/gatsby-plugin-sharp/src/gatsby-node.js","lineNumber":98,"sourceCode":"  const matchingJob = {\n    ...job,\n    args: { ...job.args, operations: [] },\n  }\n  const jobWithRemainingOperations = {\n    ...job,\n    args: { ...job.args, operations: [] },\n  }\n\n  job.args.operations.forEach(op => {\n    const operationPath = path.resolve(path.join(job.outputDir, op.outputPath))\n    if (operationPath === requestedPathOnDisk) {\n      matchingJob.args.operations.push(op)\n    } else {\n      jobWithRemainingOperations.args.operations.push(op)\n    }\n  })\n  if (matchingJob.args.operations.length === 0) {\n    throw new Error(\n      `Could not find matching operation for ${requestedPathOnDisk}`\n    )\n  }\n  return { matchingJob, jobWithRemainingOperations }\n}\n\n// So something is wrong with the reporter, when I do this in preBootstrap,\n// the progressbar gets not updated\nexports.onPostBootstrap = async ({ reporter, cache, store }) => {\n  if (process.env.gatsby_executing_command !== `develop`) {\n    // recreate jobs that haven't been triggered by develop yet\n    // removing stale jobs has already kicked in so we know these still need to process\n    for (const [contentDigest] of store.getState().jobsV2.complete) {\n      const job = await cache.get(contentDigest)\n\n      if (job) {\n        // we don't have to await, gatsby does this for us\n        _unstable_createJob(job, { reporter })","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/gatsbyjs/gatsby/blob/8b06340921ffdf23125a365b9c9923690cb62ce6/packages/gatsby-plugin-sharp/src/gatsby-node.js#L80-L116","documentation":"In gatsby-plugin-sharp, when a request comes in for a specific transformed image on disk, splitOperationsByRequestedFile walks the job's operations and partitions them into the one matching requestedPathOnDisk and the rest. If no operation's resolved outputPath equals the requested path, nothing was scheduled for that file and the function throws. This is an internal job-consistency error, not something caused by user image options directly.","triggerScenarios":"A develop/build request asks for an image output that is not part of any queued sharp job: stale cache entries pointing at deleted operations, a public/ dir manually edited, a path mismatch between outputPath casing on case-sensitive filesystems, or a bug where requestedPathOnDisk was resolved against a different outputDir than the job.","commonSituations":"Browser requests a previously-generated derivative after the source image or its transform args changed; CDN/proxy caching an old URL; running `gatsby develop` over a `public/` folder from a prior build; cross-platform path separator mismatches (Windows vs POSIX).","solutions":["Run `gatsby clean` to remove .cache and public, then rebuild so jobs and outputs are consistent.","If you cache transformed image URLs client-side, bust that cache (rename or version the URL).","Ensure outputDir and outputPath use consistent path separators; on Windows normalize with path.posix.","If it reproduces after a clean build, report it to gatsby-plugin-sharp with the requested path and the job's operations."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"function hasMatchingOperation(job, requestedPathOnDisk) {\n  return job.args.operations.some(op =>\n    path.resolve(path.join(job.outputDir, op.outputPath)) === requestedPathOnDisk\n  );\n}","typeGuard":"function jobCoversPath(job, requestedPathOnDisk) {\n  return Array.isArray(job?.args?.operations) &&\n    job.args.operations.some(op =>\n      path.resolve(path.join(job.outputDir, op.outputPath)) === requestedPathOnDisk\n    );\n}","tryCatchPattern":"try {\n  const { matchingJob, jobWithRemainingOperations } = splitOperationsByRequestedFile(job, req);\n} catch (e) {\n  // Stale cache request: 404 to the client and let the next build regenerate.\n  res.status(404).end();\n  return;\n}","preventionTips":["Run gatsby clean between incompatible builds to keep .cache/public consistent.","Bust client-side caches of image URLs when transform args change.","Normalize all paths with path.posix on Windows to avoid separator mismatches."],"tags":["gatsby-plugin-sharp","internal","job-queue","cache","image-processing"],"backgroundTag":null,"analyzedSha":"8b06340921ffdf23125a365b9c9923690cb62ce6","analyzedAt":"2026-08-13T02:36:21.405Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}