hcengineering/platform · warning
Not found
Error message
Not found
What it means
The pod-mail Express server has a catch-all middleware that responds 404 { message: 'Not found' } to any request that did not match a registered endpoint. It is not thrown by handler code — it is the terminal route-matching fallback. It means the URL path or HTTP method did not correspond to any endpoint registered via createServer.
Source
Thrown at services/mail/pod-mail/src/server.ts:48
})()
}
export function createServer (endpoints: Endpoint[]): Express {
const app = express()
app.use(cors())
app.use(express.json())
endpoints.forEach((endpoint) => {
if (endpoint.type === 'get') {
app.get(endpoint.endpoint, catchError(endpoint.handler))
} else if (endpoint.type === 'post') {
app.post(endpoint.endpoint, catchError(endpoint.handler))
}
})
app.use((_req, res, _next) => {
res.status(404).send({ message: 'Not found' })
})
app.use((err: any, _req: any, res: any, _next: any) => {
if (err instanceof ApiError) {
res.status(400).send({ code: err.code, message: err.message })
return
}
res.status(500).send({ message: err.message })
})
return app
}
export function listen (e: Express, port: number, host?: string): Server {
const cb = (): void => {
console.log(`Mail service has been started at ${host ?? '*'}:${port}`)
}View on GitHub (pinned to 63e28dc964)
Solutions
- Check the request URL against the endpoint paths registered in pod-mail's main.ts and correct the path or HTTP method.
- Confirm the client is hitting the mail pod's host:port, not another pod (pod-mail and pod-notification have identical 404 bodies).
- Inspect any reverse-proxy/gateway rewrite rules that may strip or prepend path prefixes.
- Log the full incoming req.method + req.originalUrl (temporarily add middleware before the 404 handler) to see what actually reaches the server.
Example fix
// before
await fetch('http://mail:3040/send-mail', ...)
// after (path matching the registered post endpoint)
await fetch('http://mail:3040/sendmail', { method: 'POST', ... }) Defensive patterns
Strategy: validation
Validate before calling
const MAIL_ROUTES = ['/sendmail'] // paths registered by pod-mail
function assertMailRoute(method: string, path: string) {
if (method !== 'POST' || !MAIL_ROUTES.includes(path)) throw new Error(`unknown mail route ${method} ${path}`)
} Try / catch
const res = await fetch(url, opts)
if (res.status === 404) throw new Error(`mail pod has no route for ${opts.method} ${url} — check path/method and target port`) Prevention
- Keep endpoint paths in shared constants used by both client and server registration
- Pin pod host:port per service in config to avoid cross-pod confusion
- Confirm POST vs GET per endpoint before calling
When it happens
Trigger: GET/POST to a path not in the endpoint table (e.g. wrong service prefix, wrong port routing to the wrong pod, trailing path segments), or using GET on an endpoint registered with type 'post'.
Common situations: Proxy or gateway rewriting paths and dropping/adding prefixes; calling the mail pod on the notification pod's port (or vice versa — both return the identical 404 body); API version path changed after upgrade; typo in endpoint path like /sendmail vs /send-mail.
Related errors
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/61cfbfeb32349f34.
Report an issue: GitHub.