thedotmack/claude-mem · info
Not found
Error message
Not found
What it means
createRemoteReadOnlyGuard filters remote (non-localhost) access to observation TV endpoints. When the guard's decision is 404, the middleware writes `{ error: 'Not found' }` directly, hiding the endpoint's existence from remote callers. Responses are always written inline because the worker has no terminal error handler.
Solutions
- Use the correct, current route path for the observation TV API
- Run the request from localhost if the endpoint is local-only
- Check the guard configuration to see which paths are exposed remotely
Example fix
// before
fetch('http://remote-host:37777/api/obs-tv/old-route')
// after
fetch('http://127.0.0.1:37777/api/obs-tv/current-route') Defensive patterns
Strategy: fallback
Validate before calling
// only call obs-tv routes that are in the documented remote-exposed set const isExposedRemotely = REMOTE_EXPOSED_ROUTES.includes(path);
Try / catch
if (res.status === 404) {
// remote: path not exposed; retry locally or correct the route
} Prevention
- Keep client route lists in sync with the worker's exposed API
- Treat remote 404s as possible access masking; verify locally
- Document which obs-tv routes are remote-accessible
When it happens
Trigger: A remote request hits an observation-TV path the guard classifies as nonexistent (wrong route, hidden endpoint, or deliberately masked path).
Common situations: Probing remote endpoints that only exist locally; clients constructed from outdated route lists after the route was removed/renamed; enumeration attempts being masked as 404.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/3dfe4ce1d5e2d9f2.
Report an issue: GitHub.
Appendix: source
Thrown at src/services/worker/http/middleware.ts:303
path: req.path,
presentedToken,
expectedToken: options.getToken(),
});
if (!decision.allow) {
// Never log the secret or the raw query string. `req.path` excludes the
// query string in Express, which is what makes that safe.
logRemoteDenial({
path: req.path,
method: req.method,
clientIp,
reason: decision.reason,
});
// Always write the response. The worker never calls finalizeRoutes(), so
// it has no terminal error handler — forwarding an error to Express
// would land in its default handler and return an HTML stack page.
if (decision.status === 404) {
res.status(404).json({ error: 'Not found' });
} else if (decision.status === 403) {
res.status(403).json({
error: 'Forbidden',
message: 'Observation TV remote access is read-only'
});
} else {
res.status(401).json({
error: 'Unauthorized',
message: 'Missing or invalid Observation TV token'
});
}
return;
}
// 6. Pass.
res.setHeader('Cache-Control', 'no-store');
next();
};View on GitHub (pinned to d8bc9755e7)