Compare commits

...
Author SHA1 Message Date
Sonarly Claude Code 0586704bbc chore: improve monitoring for fix: handle missing position column gracefully in
**Monitoring: Classify UNDEFINED_COLUMN/UNDEFINED_TABLE as schema mismatch instead of generic "Data validation error"**

In `compute-twenty-orm-exception.ts`, PostgreSQL errors 42703 (UNDEFINED_COLUMN) and 42P01 (UNDEFINED_TABLE) were falling through to the catch-all handler that throws a generic `PostgresException('Data validation error.', errorCode)`. This is misleading — these errors indicate a schema mismatch between the ORM metadata and the actual database schema, not a data validation problem.

The fix adds explicit handling before the catch-all that returns a `TwentyORMException` with:
- `METADATA_VERSION_MISMATCH` code — the existing, semantically correct exception code
- The original `error.message` (e.g., "column workspaceMember.position does not exist") — preserving debuggability in Sentry
- A user-friendly message: "Your workspace schema is out of date. Please refresh and try again."

This change means:
1. Sentry errors will show the actual missing column/table name instead of "Data validation error"
2. The error flows through `TwentyORMException` handling (which returns proper HTTP responses) instead of the generic `PostgresException` path
3. The `postgresSqlErrorCode` Sentry tag will no longer be needed to diagnose these — the exception message itself is descriptive
2026-03-27 13:57:41 +00:00
Sonarly Claude Code 2cbe558ca6 fix: handle missing position column gracefully in workspace member query during token renewal
https://sonarly.com/issue/19011?type=bug

When a user's refresh token is renewed, the server queries the `workspaceMember` table including the `position` column. If the workspace has not been migrated (via `sync-metadata`) to include this column, PostgreSQL throws error 42703 (undefined column), blocking the user from obtaining a new access token.

Fix: **Fix: Select only required columns in workspace member query during token renewal**

In `access-token.service.ts`, the `findOne` call on `workspaceMemberRepository` was selecting ALL columns from the `workspaceMember` table, including `position` which may not exist in workspace schemas that haven't been migrated. The code only uses `workspaceMember.id` from the result, so the fix adds a `select` clause to query only `id` and `userId` (needed for the WHERE filter).

```typescript
const workspaceMember = await workspaceMemberRepository.findOne({
  where: { userId: user.id },
  select: { id: true, userId: true },
});
```

This prevents the PostgreSQL 42703 (undefined column) error for workspaces with stale schemas, while keeping the exact same functional behavior.

**Note:** The underlying issue is that this workspace needs `sync-metadata` run to add the `position` column. The code fix prevents the auth flow from breaking for unmigrated workspaces, but the workspace should still be migrated.
2026-03-27 13:57:41 +00:00
2 changed files with 17 additions and 0 deletions
@@ -96,6 +96,10 @@ export class AccessTokenService {
where: {
userId: user.id,
},
select: {
id: true,
userId: true,
},
});
assertIsDefinedOrThrow(
@@ -58,6 +58,19 @@ export const computeTwentyORMException = async (
);
}
if (
errorCode === POSTGRESQL_ERROR_CODES.UNDEFINED_COLUMN ||
errorCode === POSTGRESQL_ERROR_CODES.UNDEFINED_TABLE
) {
return new TwentyORMException(
error.message,
TwentyORMExceptionCode.METADATA_VERSION_MISMATCH,
{
userFriendlyMessage: msg`Your workspace schema is out of date. Please refresh and try again.`,
},
);
}
if (
isDefined(errorCode) &&
Object.values(POSTGRESQL_ERROR_CODES).includes(errorCode)