Area
services/platform/convex/knowledge_entries/ — public mutations (createKnowledgeEntry, updateKnowledgeEntry, deleteKnowledgeEntry) and their shared helper (validateTopicAndContent).
Steps to reproduce
- Open the Knowledge Entries UI.
- Try to create a knowledge entry with an empty topic (or content exceeding the max length), or with a topic that already exists.
- Observe the browser console — a raw "Server Error" is surfaced instead of a structured, readable error.
Alternatively:
- Edit a superseded (non-active) entry.
- Delete a knowledge entry that no longer exists.
Expected
The client receives a ConvexError with a structured code field (following the pattern used in tasks/mutations.ts and branding/file_actions.ts) so the UI can display a user-readable message.
Actual
throw new Error(...) is used throughout, which Convex surfaces as an opaque "Server Error" in the browser console; the message is lost to the client.
Evidence
services/platform/convex/knowledge_entries/helpers.ts:46 — throw new Error('Topic is required')
services/platform/convex/knowledge_entries/helpers.ts:48 — throw new Error(\Topic exceeds ${TOPIC_MAX_LENGTH} characters`) services/platform/convex/knowledge_entries/helpers.ts:50—throw new Error('Content is required') services/platform/convex/knowledge_entries/helpers.ts:52—throw new Error(`Content exceeds ${CONTENT_MAX_LENGTH} characters`) services/platform/convex/knowledge_entries/mutations.ts:34—throw new Error('Unauthenticated')(createKnowledgeEntry)services/platform/convex/knowledge_entries/mutations.ts:53—throw new Error(`A knowledge entry for the topic "..." already exists...`) services/platform/convex/knowledge_entries/mutations.ts:86—throw new Error('Unauthenticated')(updateKnowledgeEntry)services/platform/convex/knowledge_entries/mutations.ts:90—throw new Error('Knowledge entry not found') services/platform/convex/knowledge_entries/mutations.ts:93—throw new Error('Only the active version of an entry can be edited') services/platform/convex/knowledge_entries/mutations.ts:116—throw new Error(`A knowledge entry for the topic "..." already exists.`) services/platform/convex/knowledge_entries/mutations.ts:172—throw new Error('Unauthenticated')(deleteKnowledgeEntry)services/platform/convex/knowledge_entries/mutations.ts:176—throw new Error('Knowledge entry not found')` (deleteKnowledgeEntry)
Notes
Related: #1993 (same pattern in websites/customers/vendors). The fix is to import ConvexError from "convex/values" and replace each throw with throw new ConvexError({ code: '...' }) matching the structured pattern used in tasks/mutations.ts. validateTopicAndContent in helpers.ts is called from both public mutations and internal mutations; switching it to ConvexError is safe since ConvexError propagates correctly through both paths.
Severity: medium — user-facing validation and auth errors silently become opaque "Server Error" in the console; the UI typically shows no feedback when these mutations reject.
Area
services/platform/convex/knowledge_entries/— public mutations (createKnowledgeEntry,updateKnowledgeEntry,deleteKnowledgeEntry) and their shared helper (validateTopicAndContent).Steps to reproduce
Alternatively:
Expected
The client receives a
ConvexErrorwith a structuredcodefield (following the pattern used intasks/mutations.tsandbranding/file_actions.ts) so the UI can display a user-readable message.Actual
throw new Error(...)is used throughout, which Convex surfaces as an opaque "Server Error" in the browser console; the message is lost to the client.Evidence
services/platform/convex/knowledge_entries/helpers.ts:46—throw new Error('Topic is required')services/platform/convex/knowledge_entries/helpers.ts:48—throw new Error(\Topic exceeds ${TOPIC_MAX_LENGTH} characters`)services/platform/convex/knowledge_entries/helpers.ts:50—throw new Error('Content is required')services/platform/convex/knowledge_entries/helpers.ts:52—throw new Error(`Content exceeds ${CONTENT_MAX_LENGTH} characters`)services/platform/convex/knowledge_entries/mutations.ts:34—throw new Error('Unauthenticated')(createKnowledgeEntry)services/platform/convex/knowledge_entries/mutations.ts:53—throw new Error(`A knowledge entry for the topic "..." already exists...`)services/platform/convex/knowledge_entries/mutations.ts:86—throw new Error('Unauthenticated')(updateKnowledgeEntry)services/platform/convex/knowledge_entries/mutations.ts:90—throw new Error('Knowledge entry not found')services/platform/convex/knowledge_entries/mutations.ts:93—throw new Error('Only the active version of an entry can be edited')services/platform/convex/knowledge_entries/mutations.ts:116—throw new Error(`A knowledge entry for the topic "..." already exists.`)services/platform/convex/knowledge_entries/mutations.ts:172—throw new Error('Unauthenticated')(deleteKnowledgeEntry)services/platform/convex/knowledge_entries/mutations.ts:176—throw new Error('Knowledge entry not found')` (deleteKnowledgeEntry)Notes
Related: #1993 (same pattern in websites/customers/vendors). The fix is to import
ConvexErrorfrom"convex/values"and replace each throw withthrow new ConvexError({ code: '...' })matching the structured pattern used intasks/mutations.ts.validateTopicAndContentinhelpers.tsis called from both public mutations and internal mutations; switching it toConvexErroris safe sinceConvexErrorpropagates correctly through both paths.Severity: medium — user-facing validation and auth errors silently become opaque "Server Error" in the console; the UI typically shows no feedback when these mutations reject.