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
- Retry the deploy after a short wait; transient upstream inconsistency usually clears.
- If it persists, deploy to a fresh Cloudflare Pages project name to bypass the suspect asset store state.
- 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
- Avoid concurrent deployments to the same Cloudflare Pages project, which can mutate the asset store mid-deploy.
- Treat 502 'unknown asset hash' as transient and retry with backoff before surfacing to the user.
- If the error persists across retries, redeploy under a fresh project name to bypass suspect asset-store state.
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
- Cloudflare returned a non-JSON response.
- Cloudflare API token is required.
- Cloudflare account ID is required.
- Cloudflare zone is required for a custom domain.
- Select a valid Cloudflare domain for the custom domain.
AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12).
Data as JSON: /api/errors/780744e9e5f677f7.
Report an issue: GitHub.