nexu-io/open-design · error · DeployError

Cloudflare reported an unknown asset hash: ${hash}

Error message

Cloudflare reported an unknown asset hash: ${hash}

What it means

After the daemon asks Cloudflare which asset hashes are missing (cloudflarePagesMissingAssetHashes), Cloudflare returns a subset of hashes it wants uploaded. If Cloudflare returns a hash the daemon never proposed, the response is inconsistent with the request, so the daemon aborts with status 502 rather than upload data for an unknown key.

Source

Thrown at apps/daemon/src/deploy.ts:1073

        `Cloudflare Pages assets must be ${formatMib(CLOUDFLARE_PAGES_ASSET_MAX_BYTES)} or smaller: ${file.file} is ${formatMib(data.length)}.`,
        400,
      );
    }
    const hash = cloudflarePagesAssetHash({ ...file, data });
    if (!uniqueFiles.has(hash)) {
      uniqueFiles.set(hash, {
        hash,
        data,
        contentType: file.contentType || 'application/octet-stream',
      });
    }
  }
  const hashes = Array.from(uniqueFiles.keys());
  const missing = await cloudflarePagesMissingAssetHashes(uploadToken, hashes);
  if (missing.length > 0) {
    const missingFiles = missing.map((hash) => {
      const file = uniqueFiles.get(hash);
      if (!file) throw new DeployError(`Cloudflare reported an unknown asset hash: ${hash}`, 502);
      return {
        ...file,
        hash,
      };
    });

    for (const batch of chunkCloudflarePagesAssetUploads(missingFiles)) {
      const payload = batch.map((file) => ({
        key: file.hash,
        value: file.data.toString('base64'),
        metadata: {
          contentType: file.contentType,
        },
        base64: true,
      }));
      const uploadResp = await fetch(`${CLOUDFLARE_API}/pages/assets/upload`, {
        method: 'POST',
        headers: cloudflareAssetHeaders(uploadToken, { 'Content-Type': 'application/json' }),

View on GitHub (pinned to 5be4028344)

Solutions

  1. Retry the deploy after a short wait; transient upstream inconsistency usually clears.
  2. If it persists, deploy to a fresh Cloudflare Pages project name to bypass the suspect asset store state.
  3. If reproducible, capture the deploy payload and report to Cloudflare.
Defensive patterns

Strategy: retry

Validate before calling

null

Type guard

null

Try / catch

async function deployWithRetry(token: string, files: DeployFile[], attempts = 3): Promise<void> {
  for (let i = 1; i <= attempts; i++) {
    try {
      await uploadCloudflarePagesAssets(token, files);
      return;
    } catch (err) {
      if (err instanceof DeployError && err.status === 502 && /unknown asset hash/i.test(err.message) && i < attempts) {
        await new Promise((r) => setTimeout(r, 1000 * i));
        continue;
      }
      throw err;
    }
  }
}

Prevention

When it happens

Trigger: Cloudflare's Pages direct-upload API returns a missing-hash set containing a hash that is not in the locally computed uniqueFiles map. Indicates an upstream inconsistency, a hash-calculation divergence, or a race where the asset store mutated mid-deploy.

Common situations: Transient upstream API inconsistency during concurrent deployments to the same project; extremely rare hash collision; a Cloudflare-side bug in the missing-hashes endpoint.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/780744e9e5f677f7. Report an issue: GitHub.