Skip to content

🧩 feat: Ignore Unknown Theme Color Tokens Instead of Dropping the Theme - #16529

Merged
berry-13 merged 5 commits into
canaryfrom
berry-13/theme-tolerate-unknown-colors
Sep 30, 2026
Merged

berry-13 merged 5 commits into
canaryfrom
berry-13/theme-tolerate-unknown-colors

Conversation

@berry-13

@berry-13 berry-13 commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Pull Request

Summary

Today a single color token that the reader does not know drops the whole theme. The yaml loader removes interface.theme and the deployment falls back to the default look, and the client does the same for a deployment or stored theme. Unknown appearance tokens already only warn (#16373), so a typo in one color, or a theme written for a newer version that adds a color role, costs far more than an unknown appearance property does.

Readers now ignore an unknown color token and keep the rest of the theme. The server warns with the token's path (interface.theme.modes.light.colors.<token>: Unknown light color token ignored) and leaves the token out of the served theme, so a cached client older than the server never receives a name it could reject. The client applies the same rule to the deployment theme and to persisted themes. A value that is not an RGB triplet, or a key that is not a plain lowercase token, is still rejected with its path, and a theme naming only known tokens is served unchanged. This also makes future color roles forward compatible for older readers.

Closes berry-13#198

Type of change

  • Feature

Testing

Tested environments/configuration:

  • Inline interface.theme in librechat.yaml with a misspelled color (surface-tertiary, rgb-surfce-secondary), plus a reload with a broken theme
  • Deployment and stored themes carrying an unknown rgb- color, with a valid and an invalid value
  • Chromium desktop light and dark, and mobile emulation, in the Playwright mock harness

Automated tests:

  • packages/api/src/app/loader.spec.ts: an unknown color warns and is left out of the served theme instead of dropping it
  • packages/data-provider/src/config.spec.ts: the schema accepts an unknown token name and still rejects a non-token name
  • packages/client/src/theme/context/ThemeProvider.spec.tsx and registry.spec.ts: stored themes with unknown colors apply; invalid values are rejected
  • Playwright scenarios in yaml-theme-fallback.spec.ts and theme-unknown-appearance.spec.ts
  • Jest related to the changed files in api, packages/api, packages/client, packages/data-provider and client all pass

Screenshots / recordings

No change to the default appearance. The only visible effect is that a theme with an unknown color now paints its known roles instead of falling back to the default, which the Playwright scenarios assert on computed styles.

Risk / compatibility

The color-name schema is looser: any plain lowercase token parses, and anything the server does not paint is dropped with a warning. A theme that previously failed to load because of one unknown color now loads without it. Nothing changes for valid themes or stored data.

Checklist

A color token the reader does not know, with a plain token name and an RGB
triplet value, now warns and is left out of the resolved theme, matching how
unknown appearance tokens already behave. The yaml loader, the config schema,
the client registry, stored definitions and the deployment theme all share
the one rule, so a misspelled or newer role costs only itself. An invalid
value, known token or not, and a malformed name still reject the theme.
@berry-13 berry-13 changed the title berry-13/theme-tolerate-unknown-colors 🧩 feat: Ignore Unknown Theme Color Tokens Instead of Dropping the Theme Sep 29, 2026
A client older than the server tolerates only the unknown color names it was
built to expect, so the loader now removes the tokens it warned about before
the theme is served, instead of handing a cached client a definition it could
reject whole.
@berry-13
berry-13 marked this pull request as ready for review September 30, 2026 05:37
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-30T06:13:40.323249Z 6f3a5f9 New commits
🔒 Security Review ✅ Completed 2026-09-30T05:50:31.643824Z 97b2ff1 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 97b2ff1bf3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +98 to +100
const warningIssues = collectThemeWarningIssues(theme);
const warnings = warningIssues.map(formatIssue);
const served = isPlainThemeRecord(theme) ? withoutUnknownColors(theme, warningIssues) : theme;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Sanitize themes after principal overrides are merged

When a principal-scoped DB override supplies an inline theme containing a newly accepted non-rgb- token such as surface-future, this sanitation never sees it: checkConfigTheme runs while loading the base YAML, then packages/api/src/app/service.ts merges overrides, and api/server/routes/config.js sends the resulting interfaceConfig directly. A cached pre-change client rejects that raw token and discards the entire theme, so the mixed-version protection described here only works for base YAML themes; apply equivalent validation/filtering to the final merged theme before it is served. CLAUDE.mdL145-L147

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 6f3a5f9. getAppConfig now runs the loader's theme rules on the merged config whenever a DB override replaced the theme (checkOverrideTheme in packages/api/src/app/service.ts, via checkAppConfigTheme in theme.ts). Unknown colors are left out of what /api/config and shared links serve, and an override theme the client would reject falls back to the base theme. Covered by service.spec.ts and the Playwright scenarios override-theme-unknown-color-left-out and override-theme-invalid-keeps-base.

Comment thread packages/data-provider/src/theme.ts
@berry-13
berry-13 merged commit 491ea86 into canary Sep 30, 2026
43 checks passed
@berry-13
berry-13 deleted the berry-13/theme-tolerate-unknown-colors branch September 30, 2026 07:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant