Edit Profile refuses only spaces and invisible characters in a new handle,
as the server does, yet said "Use only letters, numbers and underscores."
from desktop's stricter check, although dots, dashes and CJK handles save.
It now says what it refuses, in every locale.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With no trending feeds, Discover showed the Trending header over a blank
gap. It now says there are no trending feeds yet, as desktop does. The
filter buttons by Trending and Categories had no accessible name and are
now announced as Discover Filters buttons.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The follow-list form called its title "Custom title for this Feed". Edit
Email opened a text keyboard with autocorrect and kept Submit disabled for
an invalid address without a reason; it now checks the address like the
server does and explains it under the field.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
While a feed or list loaded, failed or was missing, the follow screen showed
only a spinner or an error, with no header to close it, and the feed error
said the list failed to load. These states now keep a Follow header with its
close button, and the feed error names the feed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With no rules, Spotlight showed "Add rule" as gray text that did nothing,
and the footer repeated "Add rule" even when rules existed. The empty list
now has an "Add rule" button, and the footer says what Spotlight
highlights and which rule wins.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The errors locales had no entry for 1008 (a guest session tried a change),
4009 (wallet withdrawals disabled) or 13008 (RSSHub instance already
added), so clients showed English text or the bare code. Every errors
locale now has them, and a test checks each code the server can send.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The server now answers a blank list title with 8005, a rules save over
newer rules with 12001 and a failed AI title with 15006. Without
translations clients showed the bare English text or the number; every
errors locale now has them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The English "Hide read" description quoted "Show unread only", while the
setting it refers to is shown title-cased as "Show Unread Only". The other
languages already quote their labels as shown.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The previous and next buttons of the media lightbox had no accessible
name. Closing a global popover such as Share moved the focus to its
invisible anchor at the pointer; it now goes back to the element the
popover was opened from, unless the user clicked somewhere else.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Free and Basic users could turn on Bring Your Own Key and add keys,
which the server ignores for their plans. The switch is now disabled for
them with a note and Upgrade; keys saved earlier stay listed so they can
be deleted, and BYOK can still be turned off.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Escape or the X button closed the Add/Edit Feed and List forms (and the
inbox and RSSHub route forms) and silently dropped what was typed. With
changes they now ask "Discard changes?" first; without any they close at
once. Edit forms start from the followed settings, so only real edits count.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The model picker was a plain div that could not take focus, and Tab in
the composer indented text instead of leaving it, so keyboard users could
not change the model. The picker is now a button named "Model: <name>",
Tab moves on from the composer, and the title that opens the chat history
is named "Chat history: <title>" instead of repeating "New Chat".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
More > Generate Title closed the menu and did nothing when the request
failed: the error was only logged. A failure now shows "Couldn't generate
a title" with the reason.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The error bubble in AI chat always said "Error occurred", and a chat
without a title was named "<date> chat" or "<date> timeline summary" with
the date in the UI language but the rest in English. Both now come from
the locale files.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A reply whose stream went silent stayed on "Thinking..." with the Stop
button for as long as the connection was open. After two minutes without
any data the reply now ends with an error that says so, and the message
can be retried.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reopening a chat whose last message got no reply said "We lost connection
before the assistant replied", also when the server had refused it for the
AI quota or the user had stopped it. The English and French notice now
just says the message got no reply, like the other languages already did.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Screen readers announced the composer's icon button, which sends a message
and stops a streaming reply, and the delete button of a chat in the
history only as "button". They are now "Send message", "Stop generating"
and "Delete Chat".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The New Task button checked a fixed limit of 10, so free and Basic users,
whose plans include no AI tasks, filled in the whole form only to be
rejected, while Plus and Pro users were stopped at 10. The limit now comes
from the plan, and the AI tab says when the plan has no tasks, with Upgrade.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On the free plan the server rejects AI sort with 402, but the toggle stayed
on over the local list, which looked sorted, and nothing was shown. A
failed AI-sorted load now turns the toggle off and shows the error, with
the Upgrade action when the plan does not include it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The unread filter's tooltip and accessible name read "Show unread Only",
unlike the "Show all" label it toggles with.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sites that refuse to be framed left View Source Content showing a blank or
broken page with no way forward, because a blocked iframe still reports a
load. The web build now shows a short notice with an Open in New Tab button
under the source page, in the panel and in the modal.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The new Spotlight description said rules only color the entry list, but
they also color the text of an opened entry and AI summaries. The copy
now names all three in every language.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The list delete warning ended in "!.." in English, Japanese and French.
The Thumbnail Ratio select sat 8px below its label because of a leftover
offset and a malformed class. In a narrow Feeds table the date column
kept its 150px and cut names to one letter; below 640px it now gives its
space to the names.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The trash icon on a custom AI shortcut removed it and its prompt at
once, with no undo, unlike deleting a BYOK provider, an MCP service or
an AI task in the same modal. It now asks first.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Spotlight tab was a lone "Add rule" button with no word on what a
rule does. It now says that rules highlight words or patterns in the
entry list and that the higher rule wins, and shows "No rules yet."
On the web, the empty Notifications list now says to add an Action with
"Notification of New Entry", reload and allow browser notifications.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Screen readers met nameless controls in Preferences: the AI shortcut,
MCP and task edit buttons and switches, Enable MCP Services and Enable
BYOK, the BYOK provider and email edit buttons, and two auth buttons both
called "Link". They now carry names such as "Edit shortcut", the item
name, "Change Email" and "Link Google".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Account, password and 2FA forms showed messages such as "Invalid string:
must match pattern /^\w+$/" or "Too small: expected string to have >=8
characters", in every language. Common text checks now say "This field
is required.", "Use at least 8 characters." and the like, translated,
and the handle and TOTP code get their own messages.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A provider saved without an API key was reported as added and marked
"Configured", but the server never uses a provider without a key. The
form now asks for the key, and a saved provider without one shows
"No API key" instead of "Configured".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Scheduling a task on the free plan ended in the English toast "Failed to
create AI task" with no way forward, in any UI language. Creating,
editing, toggling and deleting AI tasks now report errors through the
shared toaster: translated, with "Please upgrade your plan." and an
Upgrade button for plan limits, and without a second English toast.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
"Hide read" only hides read subscriptions while the unread-only filter is
on, so turning it on in the default view seemed to do nothing. Its
description now says so.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The setting is the same remembered filter the timeline header button
switches, so a quick "Show all" in the header turned the "on launch"
preference off. It is now called "Show unread only" and says that the
header button changes it and that the choice is kept for the next launch.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Saving a handle another user has failed with a bare "Internal Server
Error" toast, because the server lets the unique index reject it. After
a failed save the form now looks the handle up and, when someone else
has it, marks the Handle field with "This handle is already taken."
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
For an unverified account the Change Email form said "Email changed." and
showed the new address, but the server only sends a link to it and keeps
the old email until that link is opened. The form now says the
verification email was sent, closes, and leaves the shown email alone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Following from a Discover card, a preview or a profile opened a modal
titled "Feeds" or "Edit Feeds", built by joining two words, which also
gave "編集 フィード" in Japanese. It now uses whole phrases: Add Feed,
Edit Feed, Add List and Edit List.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Discover's Trending tab showed an empty card when a language and view
had no trending feeds or the request failed, and a category search
without matches left a blank area under the search box. Trending now
says there are no trending feeds, or shows the error with a Retry
button, and the category search says no results were found.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Searching Discover for lists said "Found 2 feeds" or "No feeds found".
The summary now follows what the search looked for and says "Found 2
lists" or "No lists found".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Preview with a required route parameter left empty only moved the focus,
because the form never rendered its errors and its inputs were not marked
invalid. Each parameter now shows "This parameter is required." and is
announced as invalid.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
These forms showed zod's generic messages, such as "Invalid string: must
match pattern /^[a-z0-9_-]+$/" for an inbox handle with a space, and
"Too small: expected string to have >=1 characters" for an empty list
title, category name or Discover search. They now say what to enter, in
every language.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Screen readers announced a bare "button" for the sidebar sort control and
its options, the category rename save and cancel, the follow "+" on
previewed feeds and lists, the Discover clear results X, the inbox copy
and edit buttons, and the list row and Manage Feeds actions. Each now has
a name, the sort trigger is a focusable button and the sort options say
which one is active.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A broken OPML file only showed the server's error, which is
"Internal Server Error" or raw parser output. The toast now says the file
could not be read, with the server text below it. Error messages read
through getFetchErrorInfo also drop the request dump the SDK appends.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The toast used the feed's own title rather than the name shown in the
sidebar and read "<feed> have been unfollowed." It now uses the custom
title when there is one, with singular wording in English and French.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The section stayed blank under its heading when there was nothing to show
or the request failed. Show an empty-state line, or an error with Retry.
Feeds without a site link and without a category were also dropped from
the list; group them by the domain of the feed URL.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Without a local sync cursor, a failed subscriptions request left the
sidebar on the "Add more feeds" empty state, as if the user followed
nothing, and nothing retried it. Show an error with Retry instead, except
for guests, who cannot load subscriptions at all.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Opening an entry URL while signed out, for example right after logging out,
answered 401 and the entry pane said "Network Error" with a Retry that
could never succeed. Show a log-in prompt with a Login button for a 401.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A "Matches Regex" condition with a pattern that does not compile saved
with a success toast, and the rule then never matched. Show the error
under the input and refuse to save while a rule has such a pattern.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
whitespace-pre also turns off wrapping and wins over text-wrap in the
Tailwind 4 output, so long ask() messages such as the delete rule warning
were cut off mid-sentence. Use whitespace-pre-line, which keeps line breaks
and wraps, and put the unsaved actions prompt in sentence case.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When GET /actions failed on a fresh device, the Actions page showed the
empty state, and saving a new rule there replaced every rule on the server.
Show a load error with Retry instead, and make saveRules refuse to send
rules before the server's rules were loaded.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A timeline with nothing in it showed the search message "No results
found." although nothing was searched. Show "No entries yet" instead.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The appearance settings shared the desktop strings, so iOS and Android
offered to show the unread count "in the dock icon" and described
special badges "in the sidebar". Use app icon and subscription list
wording on mobile.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The OTA provider fetched the store policy but never used it. Fetch it
once per launch, from the env profile's OTA URL, and show an alert when
the App Store or Google Play has a newer version. Later puts that
version off, a prompt shows at most once per launch, and a blocked
version asks every time the app returns to the foreground. APKs from
outside Google Play are not prompted, the alert waits until the app is
in front, and while it is open the review prompt stays away.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>