Repository navigation
Description
Summary
extension_version.published_by_id (added in V1_72__Trusted_Publisher.sql) is nullable at the
schema level, and the JPA/jOOQ code that reads it (ExtensionVersionJooqRepository,
ExtensionVersion.toExtensionJson(), LocalRegistryService.isVerified(), the ExtensionJson
DTO's @NotNull annotation, the webui's Extension.publishedBy type) is inconsistent about
whether a null value is possible - some paths null-check it, several ExtensionVersionJooqRepository
queries INNER JOIN user_data on it (which would silently drop, or 404, an otherwise-valid
extension/version if it were ever null), and the webui dereferences it unguarded in two spots
(extension-detail.tsx).
Investigation
This surfaced while reviewing PR #2161 (a Copilot review comment flagged one of the affected
INNER JOINs). Two theories were checked:
- Is a null value actually reachable today?
PublishExtensionVersionHandler.javais the
only place in the codebase that callsentityManager.persist()for a newExtensionVersion,
and it unconditionally setspublishedBy(line ~253) before persisting, regardless of whether
the request was authenticated viaAccessTokenAuthenticationorLoggedInAuthentication
(session-only, no token). So every future insert is guaranteed non-null. - Is it null in existing (historical) data? Restoring a production DB dump taken at migration
V1_71and migrating it tomain,SELECT * FROM extension_version WHERE published_by_id IS NULLreturns zero rows.
So the column can be made NOT NULL outright - no backfill needed, and every insert path already
satisfies it.
Proposed fix
- New Flyway migration: a defensive no-op
UPDATE ... WHERE published_by_id IS NULL(safety net
for any environment whose data might differ) followed by
ALTER TABLE extension_version ALTER COLUMN published_by_id SET NOT NULL. - Update the
ExtensionVersion#publishedByJPA mapping to@JoinColumn(nullable = false)
(or equivalent) to match. - Once enforced, the
ExtensionJson.publishedBy@NotNullannotation and the webui's
Extension.publishedBy: UserData(non-optional) type are both actually true, and none of
ExtensionVersionJooqRepository'sINNER JOIN user_data ON ... published_by_idcall sites need
to change toLEFT JOINdefensively - the constraint makes that unnecessary rather than
something to work around.
Out of scope / not needed
Making the joins LEFT JOIN and guarding the two webui .publishedBy. accesses instead of adding
the constraint was considered and explicitly rejected: it would carry extra code and API surface
for a data shape the schema can (and after this fix, will) simply disallow.
Activity
netomi commentedon Sep 30, 2026
@cstamas can you take a look here? I think that was missed as a final step of the trusted publisher migration. My understanding is that the
published_by_idcan never be null now, and we should indicate that in the places as outlined above to not confuse reviews that might assume that the field still can be null.