Replace inline errorMessage duplicates in the server - #914
Merged
Conversation
`apps/server/src/shared/lib/error-message.ts` is the canonical helper for turning an unknown catch value into a string, but 18 sites across 11 server modules had re-inlined `error instanceof Error ? error.message : String(error)` instead of importing it. This is a regression of the consolidation done in #608 — the pattern creeps back in every time a new try/catch is written. Replaced only byte-equivalent occurrences. Sites with a different fallback ("Unknown error", "Archive failed", "Invalid model.", the `.slice(0, 2_000)` truncation in browser-extension.ts) or a different result type (the variants that rethrow an `Error` rather than produce a string) are intentionally left alone — they are not the same function. No behavior change; `errorMessage()` is byte-identical to what each site inlined. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
selfcontained added a commit
that referenced
this pull request
Aug 10, 2026
Completes the errorMessage sweep started server-side in #914. apps/web carried a byte-identical reimplementation in jobs-helpers.tsx plus one inline copy in markdown.tsx; both now route through the canonical apps/server/src/shared/lib/error-message.ts. Web imports a VALUE here, so it follows the #844/#849 shape: a new dependency-free re-export module at apps/web/src/lib/errors.ts keeps call sites on "@/lib/..." instead of reaching across the boundary directly. Test coverage for the helper already exists in apps/server/test/error-message.test.ts and is a strict superset of the jobs-helpers.test.tsx block, which is dropped. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
apps/server/src/shared/lib/error-message.tsis the canonical helper for turning an unknown catch value into a string:18 sites across 11 server modules had re-inlined that exact expression instead of importing it. This replaces them with
errorMessage(...):release-checks.tsserver/release-runtime.tsjobs/service.tsupdate-migrations.tsagents/manager.ts(already imported the helper)assisted-update.tsobservability/subsystem-tracker.tspersonas/authoring.tsrelease-info.tsroutes/release.tsshared/mcp/tool-error.ts(inner branch of a longer chain)Why this is tech debt
This is a regression of the consolidation landed in #608. The tech-debt Brain has a standing pattern note that this exact helper "does not stay fixed on its own" — every new
try/catchis an opportunity to retype the ternary instead of adding the import. The duplication is harmless in isolation but it is the reason nobody can change the helper's behavior in one place.Scope / what was deliberately left alone
Only byte-equivalent occurrences were replaced. A repo-wide grep for
instanceof Errorfound 19 other sites that look similar but are not the same function, and none of them were touched:"Unknown error"(notifications/slack.ts,routes/release.ts:465,486,release-info.ts:243),"Unknown error."(server/http-helpers.ts),"Archive failed"(agents/archive.ts),"Invalid model."(routes/personas.ts),"invalid JSON metadata"(release-metadata.ts),"migration evaluation failed"(release-info.ts:211),"Failed to substitute variables."(routes/agents/terminal-routes.ts),"Database probe failed"(observability/service-resources.ts),"Prompt delivery failed."(routes/browser-extension.ts, which also truncates via.slice(0, 2_000)).release-tarball-cache.ts:210andserver/mcp-handlers.ts:577rethrow anError, not a string.config.ts:165(astartsWithguard),db/seed/run.ts:41(fallback is the raw value, notString(...)).Web-side duplicates (
apps/web/src/components/app/jobs-helpers.tsx:73reimplements the helper,components/ui/markdown.tsx:211inlines it) are not in this PR — that half needs a re-export decision through@/lib/...and stays on the tech-debt backlog for a future run.Behavior
None.
errorMessage()is byte-identical to what each replaced site inlined.Validation
pnpm run check— greenpnpm run test— green (2503 server + 705 web + 60, 0 failures)pnpm run test:e2e— 178 passed, 12 skippedfinalize:webnot run: noapps/web/files changedQueued for the next run
Backlog top item after this: the web half of this same sweep, then the
formatDatename-collision cleanup acrossactivity-chart-utils.ts/release-utils.ts/jobs-helpers.ts.🤖 Generated with Claude Code