DIYgod/RSSHub · error · Error

Invalid data received from API

Error message

Invalid data received from API

What it means

Thrown as a plain Error when the authenticated Skeb works API (/api/users/:username/works) returns a value that is falsy or not an array. Unlike the public API, this endpoint requires a valid bearer token and a request_key cookie. A non-array response typically indicates an auth failure (expired token), a rate-limit response, or that the username does not exist. The check `!data || !Array.isArray(data)` guards the subsequent data.map() call.

Source

Thrown at lib/routes/skeb/works.ts:67

    const url = `${baseUrl}/api/users/${username.replace('@', '')}/works`;

    await ensureRequestKey(url);

    const items = await cache.tryGet(url, async () => {
        const data = await ofetch(url, {
            retry: 0,
            method: 'GET',
            query: { role: 'creator', sort: 'date', offset: '0' },
            headers: {
                'User-Agent': config.ua,
                Cookie: `request_key=${await cache.get('skeb:request_key')}`,
                Authorization: `Bearer ${config.skeb.bearerToken}`,
            },
        });

        if (!data || !Array.isArray(data)) {
            throw new Error('Invalid data received from API');
        }

        return data.map((item) => processWork(item)).filter(Boolean);
    });

    return {
        title: `Skeb - ${username}'s Works`,
        link: `${baseUrl}/${username}`,
        item: items as DataItem[],
    };
}

function hasResponseData(error: unknown): error is { response: { _data: string } } {
    return error !== null && typeof error === 'object' && 'response' in error && typeof (error as { response?: { _data?: unknown } }).response?._data === 'string';
}

async function ensureRequestKey(url: string) {
    if (await cache.get('skeb:request_key')) {

View on GitHub (pinned to bed535e087)

Solutions

  1. Refresh the SKEB_BEARER_TOKEN by re-extracting it from the browser (localStorage.getItem('token')).
  2. Clear the cached request_key if it is stale: flush the Redis/cache key 'skeb:request_key' and let ensureRequestKey re-fetch it.
  3. Verify the username exists and is public by visiting https://skeb.jp/@username in a browser.
  4. Check the raw API response by curling the works endpoint with the current token and cookie to see the error body.
Defensive patterns

Strategy: try-catch

Validate before calling

if (!data || !Array.isArray(data)) {
    throw new Error('Invalid data received from API — the bearer token may be expired or the username may not exist');
}

Type guard

function isWorksArray(data: unknown): data is unknown[] {
    return Array.isArray(data);
}

Try / catch

try {
    const data = await ofetch(url, { retry: 0, /* ... */ });
    if (!isWorksArray(data)) throw new Error('Invalid data received from API');
} catch (e) {
    logger.error('Skeb works API call failed', { url, error: e });
    throw e;
}

Prevention

When it happens

Trigger: The bearer token expired and the API returns a JSON error object instead of an array; the request_key cookie is stale or missing and Skeb returns a redirect/error page; the username does not exist (404 body); or Skeb returns a rate-limit response object.

Common situations: SKEB_BEARER_TOKEN was valid when set but has since expired; the request_key cache entry (skeb:request_key) was flushed and the key-rotation logic in ensureRequestKey failed to extract a new one; or the target creator's account was deleted/made private.

Related errors


AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12). Data as JSON: /api/errors/71cd9357449c3a41. Report an issue: GitHub.