overleaf/overleaf · warning · NotFoundError
nothing cached yet
Error message
nothing cached yet
What it means
getRedirectWithFallback iterates the configured backends (clsi-cache instances) trying getLatestOutputFile; if every backend fails or returns nothing, it concludes no compile output is cached anywhere and throws NotFoundError('nothing cached yet'). It is an expected 'cold cache' signal, not a malfunction.
Source
Thrown at services/web/app/src/Features/Compile/ClsiCacheHandler.mjs:234
shard: headers.get('X-Shard') || 'cache',
lastModified: new Date(headers.get('X-Last-Modified')),
size: parseInt(headers.get('X-Content-Length'), 10),
allFiles: JSON.parse(allFilesRaw),
}
} catch (err) {
if (err instanceof RequestFailedError && err.response.status === 404) {
lastFailures.delete(url) // The shard is back up.
break // No clsi-cache instance has cached something for this project/user.
}
lastFailures.set(url, performance.now()) // The shard is unhealthy. Refresh timestamp of last failure.
logger.warn(
{ err, projectId, userId, url, shard },
'getLatestOutputFile from clsi-cache failed'
)
// This clsi-cache instance is down, try the next backend.
}
}
throw new NotFoundError('nothing cached yet')
}
/**
* Populate the clsi-cache for the given project/user with the provided source
*
* This is either another project, or a template (id+version).
*
* @param projectId
* @param userId
* @param sourceProjectId
* @param templateVersionId
* @param imageName
* @param lastUpdated
* @param shard
* @param signal
* @return {Promise<void>}
*/
async function prepareCacheSource(View on GitHub (pinned to 28ad3b03b7)
Solutions
- Trigger a compile first (call ClsiManager) so output gets populated, then request the cached file
- Verify the same projectId/userId pair used at populate time is used for lookup
- Check clsi-cache availability and logs — if all shards were down, the cache was simply never consulted
- Treat this error as 'cache miss' and fall back to the normal clsi output endpoint
Example fix
// before
const url = await ClsiCacheHandler.promises.getRedirectWithFallback(projectId, userId, file)
// after
let url
try {
url = await ClsiCacheHandler.promises.getRedirectWithFallback(projectId, userId, file)
} catch (err) {
if (err instanceof NotFoundError) {
url = await compileAndGetOutputDirectly(projectId, userId, file)
} else { throw err }
} Defensive patterns
Strategy: fallback
Try / catch
try {
url = await ClsiCacheHandler.promises.getRedirectWithFallback(projectId, userId, file)
} catch (err) {
if (err instanceof NotFoundError) {
url = await getClsiOutputDirectly(projectId, userId, file)
} else { throw err }
} Prevention
- Trigger a compile before requesting cached output
- Monitor clsi-cache health — all shards down silently degrades to this error
- Use consistent projectId/userId between populate and lookup calls
When it happens
Trigger: Requesting the latest output file redirect when no clsi-cache backend has an entry for the project/user: first compile after deployment, cache eviction/expiry, or all cache shards unreachable (swallowed per-shard errors).
Common situations: Fresh project with no prior compile; clsi-cache restarted with empty storage; cache TTL expired; user-id mismatch between the populate and lookup calls.
Related errors
- NotFoundError
- project does not exist: ${projectId}
- file does not exist
- compile in progress
- too many concurrent compile requests
AI-assisted analysis of overleaf/overleaf@28ad3b03b7 (2026-09-03).
Data as JSON: /api/errors/947f27af937e4a5e.
Report an issue: GitHub.