Known Error Database (KEDB)
The dedicated known-error record type: full field reference, publish/expire/retire lifecycle, and the portal-facing match endpoint.
Overview
A known error is a documented root cause and workaround for a recurring problem, published so agents, the self-service portal, and the virtual agent can surface it before someone opens a duplicate ticket. FlowOS stores known errors as their own collection (separate from the Problem record's known_error status — see the note below), with a full publish/expire/retire lifecycle, view/usage counters, and links back to the problem, incidents, CIs, and knowledge article it relates to.
Problem can be marked with status known_error via POST /api/itsm/problems/:id/known-error, which just flags the problem itself and stores a workaround inline on it. (2) The KnownError model documented on this page is a first-class record in its own collection (itsm_known_errors), with its own number, lifecycle, and dedicated API — this is the actual KEDB. A KnownError record can optionally reference the Problem that produced it via relatedProblemId.Model Fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| number | string | required | auto (KE-NNNN) | Human-readable identifier, generated on create. |
| title | string | required | — | Short summary of the known error. |
| description | string | optional | '' | Full description. |
| symptoms | string | optional | '' | Observable symptoms used to match incidents to this entry. |
| rootCause | string | optional | '' | Documented root cause. |
| workaround | string | optional | '' | Workaround text shown to agents/end users. |
| workaroundSteps | string[] | optional | [] | Step-by-step workaround instructions. |
| affectedCiIds | ObjectId[] | optional | [] | CMDB CIs affected (ref CmdbCi). |
| affectedCiName | string | optional | — | Denormalized CI name for display/search. |
| affectedService | string | optional | — | Affected service name. |
| affectedServiceId | string | optional | — | Affected service id. |
| ownerId / ownerName | string | optional | — | Owner of the known error entry. Defaults to the creating user’s id. |
| relatedProblemId | ObjectId | optional | — | The Problem this known error was raised from (ref Problem). |
| relatedProblemNumber / relatedProblemTitle | string | optional | — | Denormalized from the linked problem. |
| relatedIncidentIds | ObjectId[] | optional | [] | Incidents this known error’s workaround has been applied to (ref Incident). |
| relatedChangeId / relatedChangeNumber | string | optional | — | Change request tracking the permanent fix (plain string, not a ref). |
| category | string | optional | 'application' (base route) / '' (dedicated route) | Free-text category. |
| status | enum | optional | draft | draft · published · expired · retired · closed · workaround_available |
| publishedAt / publishedBy | date / ObjectId | optional | — | Set when the record is published (ref User for publishedBy). |
| expiresAt | date | optional | — | Optional expiry date for the entry. |
| reviewDate | date | optional | — | When the entry is next due for review. |
| closedAt / closedBy / closedReason | date / string / string | optional | — | Set when closed via the base route’s /close action (permanent fix applied). |
| articleId / articleNumber | ObjectId / string | optional | — | Linked knowledge base article (ref KnowledgeArticle). |
| viewCount | number | optional | 0 | Incremented every time the record is fetched by id. |
| resolvedIncidentCount | number | optional | 0 | Incremented each time a workaround is applied to an incident. |
| tags | string[] | optional | [] | Free-form labels. |
| createdBy | string | required | — | User id of the creator. |
| createdAt / updatedAt | timestamp | optional | auto | Managed by the record. |
Publish / Expire / Retire Lifecycle
- •
draft— Initial status on create. Not visible to portal users. - •
published— Set via the/publishaction. SetspublishedAtandpublishedBy. Visible to portal/self-service consumers and returned by/match. - •
expired— Set via the/expireaction, only allowed frompublished. - •
retired— Set via the/retireaction, allowed from any status. Terminal for the dedicated (portal) route; the base route can still/publisha retired-then-reopened record only if its status is draft/expired/workaround_available. - •
closed— Base route only, via/close, requiresclosedReason; represents a permanent fix applied. RecordsclosedAt,closedBy, and optionally the change that fixed it. - •
workaround_available— A valid status value accepted byPATCHon the base route, alongside the other statuses. It is treated as a publishable state for the base route’s/publishaction, but is not itself set by any lifecycle action.
Numbers are generated with the KE prefix via the shared number-generator utility (e.g. KE-0001), the same mechanism used by other ITSM record types.
Two Route Files
Known errors are served by two Fastify route files mounted at different prefixes. Both operate on the same KnownError collection but serve different audiences:
Base routes — /api/itsm/known-errors
The original agent-facing CRUD surface. Creating or editing a known error requires an ITSM problem role (problem_agent, problem_manager, itil, itsm_manager, itil_admin, or an admin/owner role). It is the only surface with /close (permanent-fix closure) and /apply-to-incident (link the workaround to an incident and add an IncidentTimeline entry). PATCH here allows changing status directly.
Dedicated routes — /api/itsm/known-errors-records
A portal-friendly resource layered on top of the same collection (see the file header comment: "Batch 2A — Known Error Dedicated Routes"). List and get-by-id default to published-only results unless the caller has a privileged role (owner, admin, superadmin, itsm_manager, knowledge_manager). It adds a /match endpoint for finding published known errors that match an incident by title text, category, or CI id — useful for suggesting a workaround while an incident is being filed. Its PATCH deliberately excludes status, publishedAt, and publishedBy from the update payload; status can only move via the /publish and /retire actions, and there is no /close or /apply-to-incident here.
# Create a known error (base route, agent-facing)
POST /api/itsm/known-errors
{
"title": "Login fails after SSO token refresh",
"symptoms": "Users see \"session expired\" immediately after SSO redirect.",
"rootCause": "Token refresh handler drops the tenant claim.",
"workaround": "Clear browser cookies for the app domain and log in again.",
"workaroundSteps": ["Log out", "Clear cookies for app.example.com", "Log in again"],
"relatedProblemId": "665f1a2b3c4d5e6f7a8b9c0d",
"category": "authentication"
}
# Publish it
POST /api/itsm/known-errors/:id/publish
# Portal: find matches for an incoming incident
GET /api/itsm/known-errors-records/match?q=SSO&category=authenticationAPI Quick Reference
Base routes — /api/itsm/known-errors
/api/itsm/known-errorsList known errors. Query: status, category, service, ci, problemId, q
/api/itsm/known-errorsCreate a known error (requires a problem/ITSM management role)
/api/itsm/known-errors/:idGet by id (increments viewCount)
/api/itsm/known-errors/:idUpdate fields, including status directly
/api/itsm/known-errors/:id/publishPublish (from draft, expired, or workaround_available)
/api/itsm/known-errors/:id/closeClose with a closedReason — permanent fix applied
/api/itsm/known-errors/:id/apply-to-incidentLink the workaround to an incident and log a timeline entry
/api/itsm/known-errors/:id/expireExpire (from published)
/api/itsm/known-errors/:id/retireRetire (from any status)
/api/itsm/known-errors/:idDelete
Dedicated (portal) routes — /api/itsm/known-errors-records
/api/itsm/known-errors-recordsList — published-only unless the caller has a privileged role. Query: status, category, q, limit
/api/itsm/known-errors-recordsCreate
/api/itsm/known-errors-records/matchFind published matches by q, category, or ciId (portal deflection)
/api/itsm/known-errors-records/:idGet by id (published-only unless privileged; increments viewCount)
/api/itsm/known-errors-records/:idUpdate fields (status is immutable here — use /publish or /retire)
/api/itsm/known-errors-records/:id/publishPublish (from draft or expired)
/api/itsm/known-errors-records/:id/retireRetire
/api/itsm/known-errors-records/:idDelete