event-catalog / event-catalog/generators

generator-openapi: schema descriptions are copied into MDX unescaped — `{...}` in a schema description breaks the entire catalog build

Open
#444 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
15
Forks
16
Avg merge
25m
Merged PRs (30d)
4

Description

`@eventcatalog/generator-openapi` writes response descriptions into the generated `index.mdx` message files verbatim. Since catalog bodies are MDX, any `{...}` in that text is parsed as a JavaScript expression, and a description containing e.g. JSDoc-style link syntax fails the whole `eventcatalog build` with:

```
Could not parse expression with acorn
Caused by: Unexpected character '@'
at eventsToAcorn (micromark-util-events-to-acorn/lib/index.js:60:71)
```

What makes this subtle is *which* description ends up in the MDX. In `getSchemasByOperationId` the response entry is built by spreading the **dereferenced schema object**:

```js
const schemaOrContent = response.content[contentType].schema || response.content[contentType];
schemas.responses[statusCode] = { ...schemaOrContent };
```

so `markdownForResponses` renders the **top-level `description` of the schema referenced by the response** — not the operation's own response `description`. Schema descriptions are exactly where code-first OpenAPI toolchains emit JSDoc text, so `{@link Foo}` shows up there routinely.

## Minimal repro

```yaml
openapi: 3.0.0
info: { title: Orders, version: 1.0.0 }
paths:
/orders/{orderId}:
get:
operationId: GetOrder
responses:
'200':
description: Ok
content:
application/json:
schema:
$ref: '#/components/schemas/OrderResponse'
components:
schemas:
OrderResponse:
type: object
description: >-
The order state. Mirrors {@link OrderSummary}: see the linked type
for field details.
properties:
id: { type: string }
```

Run `eventcatalog generate && eventcatalog build`. The generated message MDX contains:

```mdx
#### 200 OK
The order state. Mirrors {@link OrderSummary}: see the linked type for field details.
```

and the build fails with the acorn error above. Note the operation's own `description: Ok` is ignored in favor of the schema description.

## Expected behavior

Descriptions are CommonMark per the OpenAPI spec, so MDX-significant characters (`{`, and ideally stray `<`) should be escaped when embedded into the MDX body — the codebase already has `escapeSpecialCharactersThatBreakMarkdown` for the operation-level overview description, but it isn't applied to response/schema descriptions. Alternatively, validate the generated MDX and warn/skip instead of emitting a file that fails the whole build.

## Actual behavior

One `{...}` in the top-level description of any schema used as a response body breaks the entire catalog build. The acorn error also doesn't name the offending file, so tracking it down requires grepping the generated catalog.

## Impact

Anyone generating catalogs from specs they don't fully control (other teams' repos, code-generated specs where JSDoc leaks into schema descriptions) can have their catalog build broken at any time by an upstream docs edit. The same description-to-MDX approach likely affects `generator-asyncapi` too.

## Versions

- `@eventcatalog/core`: 4.4.1
- `@eventcatalog/generator-openapi`: 9.0.0 (also verified the markdown generation is identical in 7.12.12)
- Node.js: 26.x

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with getSchemasByOperationId and markdownForResponses, then compare their handling with escapeSpecialCharactersThatBreakMarkdown used for operation overviews. Run the supplied OpenAPI reproduction with eventcatalog generate and eventcatalog build; done means response schema descriptions containing MDX-significant characters no longer break the catalog build.

Written by the indexing model from the issue text.

Assessment

Tech stack
openapi, typescript
Domain
backend-api-design, documentation, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.