Repository navigation
fix(docs): sanitize emoji shortcodes in generated SDK docs - #631
Conversation
Original prompt from jason.schrader
|
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
|
Closing in favor of coordination with our vendor |
d2ab1ef to
40f5e23
Compare
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
There was a problem hiding this comment.
Perry's Review
Verdict: 💬 Comments / questions — the review is LGTM (both prior findings verified fixed; probe-tested, idempotent, CI green). Posted as a comment rather than an approval because the maintainer GitHub App on OpenRouterTeam currently lacks pull_requests:write, so the approval gate cannot carry the maintainer identity. A maintainer should re-approve once the permission is granted.
Risk: 🟢 Low
Findings, verification & risk assessment
Third-round review on 40f5e23. The prior suggestion (future-proof against unmapped Speakeasy shortcodes) and question (guard regex vs. fenced code blocks / URN-style colons) are both resolved, the script is correct and idempotent, and CI is green (gen-docs-nav SUCCESS, validate SUCCESS).
Prior findings — resolved
- Future-proofing against new Speakeasy emoji — the residual guard now fails the workflow (exit 1, file + line printed) if any standalone
:word:shortcode survives the substitution, so a newly emitted shortcode is caught at generation time instead of shipping as literal text. - Guard false positives — the regex was tightened to
(?!...):(?![\w:])lookarounds ((?<![\w:]):[a-z][a-z0-9_+-]*:(?![\w:])), which correctly ignores URN-style colon runs such asurn:ietf:params:oauth:token-type:jwtin generated docs.
What was verified this round
- Sanitize script: identical to the approved pattern in the sibling SDKs —
set -euo pipefail, repo-root resolution,docs/existence check, scoped todocs/**/*.mdx, idempotent (re-run on the branch's docs tree produces zero diff), with a probe-tested guard: an injected unmapped:sparkles:shortcode correctly fails, a URN-only line correctly passes. - Path-filter widening
docs/sdks/**→docs/**plus the script path is justified: regeneration PR #633 onmaintouched only one component page outsidedocs/sdks/, which the old filter would have skipped entirely. - Sanitize ordering in
docs-nav.yamlis correct: sanitize runs beforegen-docs-nav.shso nav regeneration sees clean files. - README/README-PYPI diffs (example call changes) are part of the already-merged Speakeasy regeneration history on the branch, not authored logic.
Delta scope
The three PR-author commits (all Devin AI) are: the original sanitize pass, the URN-guard regex fix, and the docs rewrite applying the replacements. The wide src/ churn in the file list belongs to regenerated-spec commits already on main and is not part of this review's delta.
Estimated impact: worst case is a false-positive failure of the residual guard on a future generated-docs pattern that looks like a :word: shortcode — a one-line mapping or content fix in the docs generation workflow, with no runtime, data, or security surface affected.
Risk assessment & full factor table
| Dimension | Severity | Risk | Reasoning |
|---|---|---|---|
| Implementation risk | 🟩 | Low | Script and workflow wiring are correct, idempotent, and probe-tested in review. |
| Premise risk | 🟩 | Low | Post-generation sanitization with a fail-fast residual guard is the right design. |
| Estimated impact | 🟩 | Low | Worst case is a contained CI failure in the docs pipeline, trivially correctable. |
| Risk Factor | Severity | Risk | Reasoning |
|---|---|---|---|
| Reversibility | 🟩 | Low | Revert restores the prior state; regeneration recreates output. |
| Detectability | 🟩 | Low | The residual guard fails CI on any unmapped shortcode immediately. |
| Blast radius | 🟩 | Low | Confined to the docs subtree mounted into the docs site. |
| Data integrity | None | No persisted state is touched. | |
| Financial exposure | None | No billing surface. | |
| Security and privacy exposure | None | No credential or auth path changed. | |
| Propagation | 🟩 | Low | Only the docs rendering pipeline consumes the output. |
| Availability | None | No serving path affected. | |
| Recovery cost | 🟩 | Low | A revert or one-line mapping fixes any issue. |
| Time to correct | 🟩 | Low | Guard failures surface in the same workflow run. |
…docs-emoji-shortcodes # Conflicts: # docs/operations/createkeysdata.mdx # docs/operations/createkeysresponse.mdx # docs/operations/getkeydata.mdx # docs/operations/getkeyresponse.mdx # docs/operations/listdata.mdx # docs/operations/updatekeysdata.mdx # docs/operations/updatekeysresponse.mdx
Summary
The Parameters tables on
openrouter.ai/docs/client-sdks/python/**render:heavy_minus_sign:as literal text. Speakeasy emits GitHub-flavored emoji shortcodes; GitHub expands them, Mintlify does not, and the docs site mounts this repo'sdocs/tree directly through asourceRefentry in openrouter-web'sprojects/docs/docs.json.Editing the generated MDX alone would not hold, because the next
speakeasy runrewrites it. So this PR pairs a one-time pass with a post-generation step:scripts/sanitize-docs-emoji.shrewritesdocs/**/*.mdxin place:Scoped to
docs/only.README.md,README-PYPI.md, and the workflow YAML keep their shortcodes, which render correctly on GitHub and PyPI.The script runs in
docs-nav.yamlimmediately beforegen-docs-nav.sh, the existing post-generation docs step.That workflow's path filter widens from
docs/sdks/**todocs/**. The shortcodes live throughoutdocs/components,docs/operations, anddocs/errorsas well, and the old filter would skip a generation PR that touched only those trees.Regeneration PR chore: 🐝 Update SDK - Generate (spec change merged) 1.1.41 #633 landed on
mainwhile this PR was open and is exactly that case: its only docs change wasdocs/components/outputfusionservertoolitem.mdx, soDocs navigationwas skipped whilePR Validationran. The widened filter is what closes it.The one-time pass: 1,429 files, 7,719 shortcodes replaced (rebased onto
mainon 2026-10-03).scripts/sanitize-docs-emoji.shends with a residual guard: if any standalone:[a-z][a-z0-9_+-]*:token (not preceded or followed by a word character or:) survives the substitution, it prints the file and line and exits non-zero, so a new shortcode Speakeasy starts emitting fails at generation time instead of shipping as literal text. Zero matches remain today, so the guard passes on current output.Verification
docs/; the six:warning:occurrences in workflow YAML are untouched.Rebase (2026-10-03)
Reopened after Pylon #4403 reported the same bug from a customer. The vendor's suggested script only rewrites
descriptionfields in OpenAPI files, and the spec has no shortcodes in it, so it doesn't fix this. The shortcodes come from Speakeasy's docs templates.Rebuilt on current
main: same.githubandscriptschanges, then the one-time pass was re-run fresh instead of replaying the old generated-docs commits.The residual guard now ignores URN-style colon runs. New OAuth docs on
maincontainurn:ietf:params:oauth:token-type:jwt, which the old pattern flagged as:params:etc.:Link to Devin session: https://openrouter.devinenterprise.com/sessions/1589ee9058c442958d427eac4e989f11
Open in Devin Desktop: https://openrouter.devinenterprise.com/desktop/session/1589ee9058c442958d427eac4e989f11?variant=devin