HeyPuter/puter · error · HttpError
subject_does_not_exist
subject_does_not_exist
Error message
Entry not found: uid=${uid} What it means
Thrown (HTTP 404) by LegacyFSController.updateFsentryThumbnail when no fs entry exists for the supplied uid, or the entry has no path. The lookup uses stores.fsEntry.getEntryByUuid(uid); a missing/null entry or one without a path is reported as subject_does_not_exist.
Source
Thrown at src/backend/controllers/fs/LegacyFSController.ts:1075
throw new HttpError(400, 'Missing `uid`', {
legacyCode: 'bad_request',
});
if (!thumbnail)
throw new HttpError(400, 'Missing `thumbnail`', {
legacyCode: 'bad_request',
});
// Only inline image data. Clients generate the thumbnail themselves
// and the thumbnails extension is what turns it into a storage
// pointer; accepting a pointer here would let a caller name an object
// the server would then sign reads of, and delete, on their behalf.
if (!thumbnail.startsWith('data:'))
throw new HttpError(400, '`thumbnail` must be a data: URL', {
legacyCode: 'bad_request',
});
const entry = await this.stores.fsEntry.getEntryByUuid(uid);
if (!entry || !entry.path)
throw new HttpError(404, `Entry not found: uid=${uid}`, {
legacyCode: 'subject_does_not_exist',
});
await assertAccess(
this.services.acl,
this.services.fs,
actor,
entry.path,
'write',
);
// emitAndWait is required: the thumbnails extension rewrites
// `event.url` from a data URL to an `s3://` pointer, and the DB
// write below needs to see that rewrite.
const event = { url: thumbnail };
await this.clients.event.emitAndWait('thumbnail.created', event, {});
await this.clients.db.write(
'UPDATE `fsentries` SET `thumbnail` = ? WHERE `uuid` = ?',View on GitHub (pinned to 908ec23eda)
Solutions
- Re-fetch the entry to confirm it exists and obtain its current uuid before calling.
- Ensure you pass the entry's uuid (string) field, not its numeric id or name.
- Handle 404 gracefully in the UI (e.g. offer to retry or discard the stale reference).
Example fix
// before
updateFsentryThumbnail({ uid: 'maybe-old-id', thumbnail: dataUrl });
// after
const entry = await getEntry(path);
updateFsentryThumbnail({ uid: entry.uuid, thumbnail: dataUrl }); Defensive patterns
Strategy: try-catch
Validate before calling
const entry = await store.getEntryByUuid(uid);
if (!entry || !entry.path) throw new Error('Entry not found for uid'); Type guard
null
Try / catch
try {
await updateFsentryThumbnail({ uid, thumbnail });
} catch (e) {
if (e.code === 'subject_does_not_exist' || e.status === 404) {
// refresh or discard the stale uid reference
} else throw e;
} Prevention
- Pass the entry uuid, not the numeric id or name.
- Re-resolve entries cached across sessions before use.
- Treat 404 as a signal to refresh the file list.
When it happens
Trigger: Passing a uid that was never created, was deleted, belongs to another user (when lookup is scoped), or a uid typo. Also an entry row that exists but has a null path.
Common situations: Using a stale uid cached after the file was deleted; passing the entry's id (numeric DB id) instead of its uuid; uid copy/paste errors.
Related errors
AI-assisted analysis of HeyPuter/puter@908ec23eda (2026-08-12).
Data as JSON: /api/errors/09cf684fbbc5b65f.
Report an issue: GitHub.