Skip to content

plugin-auth: audienceLogError detaches the logger method from its receiver — class-based host loggers crash (reading 'writeErrorLike'), turning audience 4xx refusals into 500s that hide the verdict #12773

Description

@os-zhuang

Found on a real isolated-posture dogfood boot (epic #12701 program, 2026-08-27). Small, one-line class of fix; the cost is real because the crash swallows the admission verdict the operator needs.

Measured

On the EE composed deployment (framework main, @objectstack/organizations runtime), every audience-gate refusal that routes through audienceLogError answers HTTP 500 with this in the server log:

ERROR [Better Auth]: TypeError: Cannot read properties of undefined (reading 'writeErrorLike')
at error (file:///.../packages/core/dist/index.js:650:10)
at _AuthManager.audienceLogError (file:///.../packages/plugins/plugin-auth/dist/index.mjs:5460:38)

The refusal it was trying to log (in our run: "the declared self-registration permission set '…' cannot be resolved") never reaches the caller or the log — the client sees 500 null, and the operator diagnoses blind.

Root cause (source-level)

packages/plugins/plugin-auth/src/auth-manager.ts:3499:

(logger?.error??logger?.warn)?.(message,meta);

The ?? expression extracts the method from the logger before calling it, so the call runs with this === undefined. A plain-closure logger (most test doubles) survives; @objectstack/core's class-based logger dereferences this.writeErrorLike inside error() and throws. That is why no suite caught it — the receiver-sensitive logger only appears in real compositions.

Fix shape: keep the fallback, keep the receiver — logger?.error ? logger.error(message, meta) : logger?.warn?.(message, meta) (or .call(logger, …)); a regression pin with a class-based logger double whose methods read this.

Same-pattern sweep suggestion: grep the repo for (logger?.error ?? logger?.warn) and sibling detach-then-call shapes — this one probably has family.

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions