anomalyco/sst · error
hash %s not found in manifest
Error message
hash %s not found in manifest
What it means
During uploadAssets, a hash sent by Cloudflare in an upload bucket could not be matched back to any path in the local AssetManifest (the manifest maps file path -> {hash,size,contentType}). This means the manifest handed to the upload session is out of sync with the files that session is asking for.
Source
Thrown at pkg/server/resource/cloudflare-worker-assets.go:230
}
func (r *WorkerAssets) uploadAssets(manifest AssetManifest, directory, accountId, apiToken string, hashes []string, jwt string) (string, error) {
var body bytes.Buffer
writer := multipart.NewWriter(&body)
for _, hash := range hashes {
// Find the file path for this hash in the manifest
var fileKey string
var contentType string
for path, entry := range manifest {
if entry.Hash == hash {
fileKey = path
contentType = entry.ContentType
break
}
}
if fileKey == "" {
return "", fmt.Errorf("hash %s not found in manifest", hash)
}
// Read file content
absFilePath := filepath.Join(directory, fileKey)
fileContent, err := os.ReadFile(absFilePath)
if err != nil {
return "", fmt.Errorf("failed to read file %s: %w", absFilePath, err)
}
// Base64 encode the file content
encodedContent := base64.StdEncoding.EncodeToString(fileContent)
// Create form field with content type header
part, err := writer.CreatePart(map[string][]string{
"Content-Disposition": []string{fmt.Sprintf(`form-data; name="%s"; filename="%s"`, hash, hash)},
"Content-Type": []string{contentType},
})
if err != nil {View on GitHub (pinned to a0bd20f762)
Solutions
- Re-run the deploy without touching the assets directory so the manifest and files are consistent.
- Regenerate the asset manifest from the current build output and redeploy.
- Verify every entry.Hash in the manifest matches the actual file hash of the file at that path.
- Ensure the same manifest object is passed to both uploadAssetManifest and uploadAssets (no mutation in between).
- Check for concurrent builds writing to the same output directory during deploy.
Example fix
// before: manifest generated at build time, reused later after files changed
const manifest = JSON.parse(fs.readFileSync(".old-manifest.json"));
// after: rebuild manifest from current files immediately before upload
const manifest = buildManifestFromDirectory(assetDir); Defensive patterns
Strategy: validation
Validate before calling
// before upload: every file hash in manifest must match the on-disk file,
// and the manifest must be freshly generated from the same build output
import { createHash } from "crypto";
function validateManifest(manifest, dir) {
for (const [file, entry] of Object.entries(manifest)) {
const p = path.join(dir, file);
if (!fs.existsSync(p)) throw new Error(`manifest file missing: ${p}`);
const h = createHash("md5").update(fs.readFileSync(p)).digest("hex");
if (h !== entry.hash) throw new Error(`stale manifest: hash mismatch for ${file}`);
}
} Try / catch
try {
await uploadAssets(manifest, dir);
} catch (e) {
if (/hash .* not found in manifest/.test(String(e))) {
throw new Error("Manifest out of sync with build output - regenerate the manifest and redeploy without modifying assets mid-deploy");
}
throw e;
} Prevention
- Always generate the manifest immediately before upload from the same build output
- Never mutate or trim the manifest between session init and upload
- Avoid concurrent builds writing to the same asset directory
- Freeze (don't edit) assets during a deployment
When it happens
Trigger: The manifest provided to handleUpload differs from the manifest used to initialize the session (stale build output), a file was rebuilt/changed between manifest generation and upload so hashes no longer match, or the manifest was trimmed/deduplicated incorrectly so a hash entry is missing.
Common situations: Editing files in the asset directory while a deploy is running; a build step regenerating assets after the manifest was computed; caching a manifest from a previous deploy and reusing it; content-addressing collisions or hash computation mismatch between local tooling and Cloudflare.
Related errors
- Build metadata file not found at "${filePath}". Update your
- Build ID not found in ".next/BUILD_ID" for site "${name}". E
- SolidStart's app.config.ts must be configured to use the "aw
- React Router assets directory not found at: "${assetsPath}
- TanStack Start assets directory not found at: "${assetsPat
AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30).
Data as JSON: /api/errors/9f992ebd581f5577.
Report an issue: GitHub.