hcengineering/platform · error · ApiError
File ${file} not found
Error message
File ${file} not found What it means
The /convert/:file endpoint first checks that the requested file exists in the workspace's storage via storageAdapter.stat. If no object with that name exists, the endpoint throws this 404 ApiError. Conversion never runs on missing files.
Source
Thrown at services/print/pod-print/src/server.ts:251
const printId = `print-${generateId()}`
await storageAdapter.put(ctx, wsIds, printId, printRes, `application/${options.kind}`, printRes.length)
res.contentType('application/json')
res.send({ id: printId })
})
)
app.get(
'/convert/:file',
wrapRequest(async (req, res, wsUuid) => {
const convertableFormats = ['application/vnd.openxmlformats-officedocument.wordprocessingml.document']
const ctx = req.ctx
const file = req.params.file
const stat = await storageAdapter.stat(ctx, wsUuid, file)
if (stat === undefined) {
throw new ApiError(404, `File ${file} not found`)
}
if (!convertableFormats.includes(stat.contentType)) {
throw new ApiError(400, `File of this type (${stat.contentType}) cannot be converted`)
}
const convertId = getConvertId(file, stat.etag)
const convertStats = await storageAdapter.stat(ctx, wsUuid, convertId)
if (convertStats === undefined) {
const originalFile = await storageAdapter.read(ctx, wsUuid, file)
if (originalFile === undefined) {
throw new ApiError(404, `File ${file} not found`)
}
const htmlRes = await ctx.with('convertToHtml', {}, () => convertToHtml(Buffer.concat(originalFile as any)))
View on GitHub (pinned to 63e28dc964)
Solutions
- Verify the file identifier is the exact storage key used at upload time (from storageAdapter.put / upload response).
- Confirm the request token resolves to the same workspace the file was uploaded to.
- Re-upload the file if it was deleted, then convert.
- List/stat the object first to confirm existence before calling convert.
Example fix
// before
await fetch(`/convert/${displayName}.docx`, { headers })
// after
const stat = await fetch(`${storageUrl}/${fileKey}`, { method: 'HEAD', headers })
if (stat.ok) await fetch(`/convert/${encodeURIComponent(fileKey)}`, { headers }) Defensive patterns
Strategy: validation
Validate before calling
async function assertFileExists (fileKey: string, headers: HeadersInit): Promise<void> {
const res = await fetch(`/convert/${encodeURIComponent(fileKey)}`, { method: 'HEAD', headers })
// Endpoint itself 404s; verify via your own upload registry instead:
if (!uploadedKeys.has(fileKey)) throw new Error(`File key not uploaded to this workspace: ${fileKey}`)
} Try / catch
try {
const res = await fetch(`/convert/${encodeURIComponent(fileKey)}`, { headers })
if (res.status === 404) {
const body = await res.json()
throw new Error(`File missing in workspace storage: ${body.message}`)
}
return await res.json()
} catch (err) { /* handle: re-upload or surface to user */ } Prevention
- Keep a client-side record of storage keys returned at upload time and use those exact keys.
- Encode the file key in the path; avoid using display names as keys.
- Handle workspace tokens carefully — files live per workspace.
- Treat deleted files as terminal: don't retry 404s, prompt re-upload.
When it happens
Trigger: GET /convert/:file where the file key doesn't exist in the workspace storage — wrong file name/UUID, file uploaded to a different workspace, or file already deleted/purged from the storage adapter.
Common situations: Client caching file names after the document was deleted; using a display filename instead of the storage key; cross-workspace token used against another workspace's files; typos in the path parameter.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- No such key
- No such storage key
- Cannot create message, group not found: cardId = ${event.car
- Missing response body
- Network error ${error}
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/a42333fa1b3d3b68.
Report an issue: GitHub.