HeyPuter/puter · critical · HttpError
unauthorized
unauthorized
Error message
Authentication required
What it means
Thrown by `#requireActor` when the ALS `Context` has no `actor` set — i.e. the request reached the driver without a resolved, authenticated actor. This is a precondition guard called at the start of every mutating app operation. Returns HTTP 401 with legacyCode `unauthorized`.
Source
Thrown at src/backend/drivers/apps/AppDriver.js:767
// Malformed config value — nothing to reserve from it.
}
}
if (reserved.has(hostname)) {
throw new HttpError(
400,
'`index_url` cannot point at a Puter system host',
{ legacyCode: 'bad_request' },
);
}
}
// -- Permission checks --------------------------------------------
#requireActor() {
const actor = Context.get('actor');
if (!actor)
throw new HttpError(401, 'Authentication required', {
legacyCode: 'unauthorized',
});
return actor;
}
#requireUserOrAppActor(actor) {
if (!actor.user)
throw new HttpError(403, 'User actor required', {
legacyCode: 'forbidden',
});
}
async #resolve({ uid, id }) {
if (uid) return this.#getByUidWithAlias(uid);
if (id?.uid) return this.#getByUidWithAlias(id.uid);
if (id?.name) return this.appStore.getByName(id.name);
if (id?.id) return this.appStore.getById(id.id);
if (typeof id === 'number') return this.appStore.getById(id);View on GitHub (pinned to 908ec23eda)
Solutions
- Ensure the calling route carries the auth gate (`RouteOptions` auth) so actor context is populated.
- In background/internal callers, set the actor in Context before invoking the driver.
- Authenticate the request (send a valid token) before retrying.
Example fix
// before
router.post('/apps/update', (req, res) => driver.update({...req.body}));
// after
router.post('/apps/update', { auth: true }, (req, res) => driver.update({...req.body})); Defensive patterns
Strategy: validation
Validate before calling
// This is an auth-context precondition; validate the request is authenticated
if (!req.user && !req.session) return res.status(401).send('auth required');
// and ensure the route has the auth gate so Context.actor is set Try / catch
try {
await driver.update({ uid, object });
} catch (e) {
if (e.code === 'unauthorized') { /* redirect to login */ return; }
throw e;
} Prevention
- Always attach the auth RouteOption to routes that call app driver mutations.
- Set actor in Context for internal/background callers before invoking the driver.
- Authenticate the client before allowing the call.
When it happens
Trigger: Calling an app driver method (create/update/delete/upsert) in a code path where `Context.get('actor')` is unset: an unauthenticated request, a background job that forgot to set actor context, or a misconfigured route missing the auth gate.
Common situations: A controller/route missing the `auth` RouteOption so the request is anonymous by the time it hits the driver; an extension calling the driver directly without establishing actor context; tests that bypass middleware.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
AI-assisted analysis of HeyPuter/puter@908ec23eda (2026-08-12).
Data as JSON: /api/errors/9f77b2fa66fee782.
Report an issue: GitHub.