{"record":{"id":"0253012e2a997430","repo":"DIYgod/RSSHub","slug":"category-categoryslug-not-found","errorCode":null,"errorMessage":"Category \"${categorySlug}\" not found","messagePattern":"Category \"(.+?)\" not found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/routes/secretsanfrancisco/rss.tsx","lineNumber":49,"sourceCode":"    handler,\n};\n\nasync function handler(ctx) {\n    const baseUrl = 'https://secretsanfrancisco.com';\n    const categoryApiPath = '/wp-json/wp/v2/categories';\n    const postApiPath = '/wp-json/wp/v2/posts';\n\n    // get category number\n    const categorySlug = ctx.req.param('category') || '';\n\n    let category;\n    if (categorySlug) {\n        category = await cache.tryGet(`${baseUrl}${categoryApiPath}`, async () => {\n            const { data } = await got(`${baseUrl}${categoryApiPath}`, {\n                searchParams: { slug: categorySlug },\n            });\n            if (!data || data.length === 0) {\n                throw new Error(`Category \"${categorySlug}\" not found`);\n            }\n            return data[0];\n        });\n    }\n\n    const categoryId = category?.id;\n    const categoryName = category?.name;\n    const categoryLink = category?.link;\n\n    // get posts\n    const postsUrl = `${baseUrl}${postApiPath}`;\n    const postsResponse = await got(postsUrl, {\n        searchParams: {\n            per_page: ctx.req.query('limit') ? Number.parseInt(ctx.req.query('limit')) : 10,\n            _embed: '',\n            ...(categoryId && { categories: categoryId }),\n        },\n    });","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/secretsanfrancisco/rss.tsx#L31-L67","documentation":"Thrown when the Secret San Francisco WordPress categories API returns an empty array for the requested category slug. The route looks up the numeric category id via /wp-json/wp/v2/categories?slug={categorySlug}; an empty response means no WordPress category matches that slug.","triggerScenarios":"GET {baseUrl}/wp-json/wp/v2/categories?slug={categorySlug} returns [] (data.length === 0). The category slug supplied in the route path does not match any term slug in the site's WordPress taxonomy.","commonSituations":"The subscriber mistyped the category slug; the category was renamed/removed on the WordPress site; trailing/leading characters or case mismatch (slugs are case-sensitive); a cached negative result under the cache key blocks re-resolution until expiry.","solutions":["Confirm the slug exists: open {baseUrl}/wp-json/wp/v2/categories and find the matching slug.","Correct the route URL to use the exact, lowercase WordPress slug.","Flush the cache key for the categories endpoint so a corrected slug is re-resolved immediately.","If the category was renamed, update the route example / any radar mappings."],"exampleFix":"// before\nif (!data || data.length === 0) {\n    throw new Error(`Category \"${categorySlug}\" not found`);\n}\n\n// after — same throw, but invalidate the cached lookup so a corrected slug works next time\nif (!data || data.length === 0) {\n    await cache.del(`${baseUrl}${categoryApiPath}`);\n    throw new Error(`Category \"${categorySlug}\" not found on ${baseUrl}`);\n}","handlingStrategy":"validation","validationCode":"// Pre-validate the slug shape (lowercase, no spaces) and probe the WP API.\nfunction isValidSlug(slug: string): boolean {\n    return /^[a-z0-9-]+$/.test(slug);\n}\nif (categorySlug && !isValidSlug(categorySlug)) {\n    throw new InvalidParameterError(`Invalid category slug: ${categorySlug}`);\n}","typeGuard":"const isWpCategory = (o: any): o is { id: number; name: string; link: string } =>\n    o !== null && typeof o === 'object' && typeof o.id === 'number';","tryCatchPattern":"try {\n    category = await cache.tryGet(`${baseUrl}${categoryApiPath}`, lookup);\n} catch (e) {\n    if (e instanceof Error && /not found/.test(e.message)) {\n        return ctx.json({ error: `Category '${categorySlug}' does not exist on ${baseUrl}.` }, 404);\n    }\n    throw e;\n}","preventionTips":["Validate the slug format before the API call to catch obvious typos.","Invalidate the cached categories lookup on a 'not found' so a corrected slug resolves immediately.","Expose the list of valid slugs (via /wp-json/wp/v2/categories) in route documentation."],"tags":["api","wordpress","user-input","data-validation","cache"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}