thedotmack/claude-mem · error
NotFound
NotFound
Error message
Project not found
What it means
GET /v1/projects/:id loads the project via ProjectsRepository.getById(id); a null return yields 404 NotFound 'Project not found'. The 404 fires only after ensureProjectAllowed passes, so even a correctly-scoped key gets 404 when the row is unknown or was deleted.
Source
Thrown at src/server/routes/v1/ServerV1Routes.ts:110
this.audit(req, 'projects.list');
});
app.post('/v1/projects', writeAuth, this.handleCreate(CreateProjectSchema, (req, res, body) => {
if (req.authContext?.projectId) {
res.status(403).json({ error: 'Forbidden', message: 'Project-scoped API keys cannot create projects' });
return;
}
const project = new ProjectsRepository(this.options.getDatabase()).create(body);
this.audit(req, 'project.create', project.id);
res.status(201).json({ project });
}));
app.get('/v1/projects/:id', readAuth, (req, res) => {
const id = this.routeParam(req.params.id);
if (!this.ensureProjectAllowed(req, res, id)) return;
const project = new ProjectsRepository(this.options.getDatabase()).getById(id);
if (!project) {
res.status(404).json({ error: 'NotFound', message: 'Project not found' });
return;
}
this.audit(req, 'project.read', project.id);
res.json({ project });
});
app.post('/v1/sessions/start', writeAuth, this.handleCreate(CreateServerSessionSchema, (req, res, body) => {
if (!this.ensureProjectAllowed(req, res, body.projectId)) return;
const session = new ServerSessionsRepository(this.options.getDatabase()).create(body);
this.audit(req, 'session.start', session.id, session.projectId);
res.status(201).json({ session });
}));
app.post('/v1/sessions/:id/end', writeAuth, (req, res) => {
const id = this.routeParam(req.params.id);
const repo = new ServerSessionsRepository(this.options.getDatabase());
const existing = repo.getById(id);
if (!existing) {View on GitHub (pinned to e2d1df569a)
Solutions
- List projects with GET /v1/projects and copy a current id (project-scoped keys see only their own project)
- Verify the client points at the server/database where the project lives
- Treat 404 as terminal for that id: re-list and use a fresh one instead of retrying
Defensive patterns
Strategy: validation
Validate before calling
async function getProjectOrFail(base: string, key: string, id: string) {
const res = await fetch(`${base}/v1/projects/${encodeURIComponent(id)}`, { headers: { Authorization: `Bearer ${key}` } });
if (res.status === 404) {
const { projects } = await (await fetch(`${base}/v1/projects`, { headers: { Authorization: `Bearer ${key}` } })).json();
throw new Error(`project ${id} not found; available: ${projects.map((p: { id: string }) => p.id).join(', ')}`);
}
return res.json();
} Type guard
function isNotFoundResponse(status: number, body: unknown): body is { error: 'NotFound'; message: string } {
return status === 404 && typeof body === 'object' && body !== null && (body as { error?: string }).error === 'NotFound';
} Try / catch
const res = await fetch(url, { headers });
const body = await res.json().catch(() => ({}));
if (isNotFoundResponse(res.status, body)) {
// terminal: drop cached id, re-list projects, do not retry the same id
cache.delete(id);
return null;
} Prevention
- Fetch project ids dynamically via GET /v1/projects instead of hardcoding
- Keep one config source of truth per environment for ids
- Treat 404 as terminal, never as a retryable error
When it happens
Trigger: GET /v1/projects/<id> where the id does not exist: typo in the URL, a stale id from another environment's database, or a project deleted between listing and fetching.
Common situations: Environment drift (staging ids used against prod); hardcoded project ids in scripts; a project concurrently deleted by another client.
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@e2d1df569a (2026-08-20).
Data as JSON: /api/errors/36b2702b45841d7b.
Report an issue: GitHub.