DIYgod/RSSHub · error · Error
Unable to locate Obsidian community search API config
Error message
Unable to locate Obsidian community search API config
What it means
Thrown when the regex extraction of the Obsidian community search API configuration fails. The `getSearchConfig` function fetches the HTML of `https://community.obsidian.md/search` and attempts to match two regex patterns: one for escaped JSON (`apiKey\":\"`) and one for unescaped JSON (`"apiKey":"`). If neither matches, the apiKey and Typesense URL cannot be extracted and the route cannot proceed.
Source
Thrown at lib/routes/obsidian/utils.ts:76
export function getTitle(path: string): string {
const match = path.match(titleRegex);
return match ? match[1] : '';
}
function getSearchPageUrl(type: CommunityEntryType) {
const url = new URL(searchPageBaseUrl);
url.searchParams.set('type', type);
url.searchParams.set('sort', 'created');
return url.href;
}
async function getSearchConfig(pageUrl: string): Promise<CommunitySearchConfig> {
const html = await ofetch<string>(pageUrl);
const match = html.match(/apiKey\\":\\"([^"\\]+)\\"[\s\S]*?url\\":\\"([^"\\]+)\\"/) ?? html.match(/"apiKey":"([^"]+)"[\s\S]*?"url":"([^"]+)"/);
if (!match) {
throw new Error('Unable to locate Obsidian community search API config');
}
return {
apiKey: match[1],
url: match[2].replaceAll(String.raw`\/`, '/'),
};
}
function buildItem(document: CommunitySearchHit['document']): DataItem {
return {
title: document.name,
description: document.short_desc,
link: `https://community.obsidian.md/${document.type}s/${document.slug}`,
guid: `${document.type}:${document.id}`,
pubDate: document.github_created_at ? parseDate(document.github_created_at) : undefined,
updated: document.latest_release_at ? parseDate(document.latest_release_at) : document.github_updated_at ? parseDate(document.github_updated_at) : undefined,
author: document.authors?.join(', '),
category: document.tags,View on GitHub (pinned to bed535e087)
Solutions
- Open `https://community.obsidian.md/search?type=plugin&sort=created` in a browser and view the page source to find how the apiKey and search URL are currently embedded.
- Update the regex patterns on line 73 of `lib/routes/obsidian/utils.ts` to match the new HTML format.
- If the config is now loaded via a separate JS file or API call, refactor `getSearchConfig` to fetch from the new source.
- Check if the page returns a Cloudflare challenge and consider whether Puppeteer or a different fetch strategy is needed.
Example fix
// before
const match = html.match(/apiKey\\":\\"([^"\\]+)\\"[\s\S]*?url\\":\\"([^"\\]+)\\"/) ?? html.match(/"apiKey":"([^"]+)"[\s\S]*?"url":"([^"]+)"/);
// after — broader, order-independent matching
const apiKeyMatch = html.match(/"?apiKey"?\s*[:=]\s*"([^"]+)"/);
const urlMatch = html.match(/"?url"?\s*[:=]\s*"(https?:\\/\\/[^"]+)"/);
if (!apiKeyMatch || !urlMatch) {
throw new Error('Unable to locate Obsidian community search API config');
} Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check: fetch the page and verify config is extractable before proceeding
const html = await ofetch<string>(pageUrl);
const hasConfig = /apiKey/.test(html) && /url/.test(html);
if (!hasConfig) {
throw new Error('Obsidian community page does not contain expected search config markers');
} Try / catch
try {
const searchConfig = await getSearchConfig(pageUrl);
// proceed with searchConfig...
} catch (e) {
if (e instanceof Error && e.message.includes('Unable to locate')) {
logger.error('Obsidian community HTML structure may have changed');
// Optionally fall back to a known Typesense endpoint
}
throw e;
} Prevention
- Make regex patterns more flexible to handle different JSON escaping variants.
- Test the regex against the live HTML periodically.
- Consider extracting config from a script tag by parsing it as JSON rather than regex.
When it happens
Trigger: The Obsidian community forum (Discourse) changed its HTML structure, removed the embedded search config, or changed the serialization format. The page loaded but the JSON blob containing apiKey/url was not present. A CDN or error page was returned instead of the real search page.
Common situations: Obsidian updated their Discourse instance and changed how the Typesense search config is embedded. The community page returned a Cloudflare challenge page instead of real HTML. The regex patterns are too rigid for the current JSON escaping variant.
Related errors
- Failed to find article content.
- Failed to find article content.
- api error
- WapHomeRenderData 数据未找到
- Invalid Engine Value: ${engine}, please check your config.
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/ec26d24db1202f9e.
Report an issue: GitHub.