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

  1. Use the correct, current route path for the observation TV API
  2. Run the request from localhost if the endpoint is local-only
  3. 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

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)