DIYgod/RSSHub · error
WASM function not available
Error message
WASM function not available
What it means
Generic Error thrown by the manga-update route when the WebAssembly module fails to expose the expected genReqSign function after instantiation. The route downloads a .wasm binary from Bilibili's CDN, instantiates it via Go's WASM runtime, and checks globalThis.genReqSign. If the WASM module is corrupted, the URL is stale, or the runtime doesn't support the module, the function is undefined.
Source
Thrown at lib/routes/bilibili/manga-update.ts:47
async function genReqSign(query, body) {
// Don't import on top-level to avoid a cyclic dependency - wasm-exec.js generated via `pnpm build`, which in turn needs wasm-exec.js to import routes correctly
const { Go } = await import('./wasm-exec');
// Cache the wasm binary as it's quite large (~2MB)
// Here the binary is saved as base64 as the cache stores strings
const wasmBufferBase64 = await cache.tryGet('bilibili-manga-wasm-20250208', async () => {
const wasmResp = await got('https://s1.hdslb.com/bfs/manga-static/manga-pc/6732b1bf426cfc634293.wasm', {
responseType: 'arrayBuffer',
});
return Buffer.from(wasmResp.data).toString('base64');
});
const wasmBuffer = Buffer.from(wasmBufferBase64, 'base64');
const go = new Go();
const { instance } = await WebAssembly.instantiate(wasmBuffer, go.importObject);
go.run(instance);
if (void 0 === globalThis.genReqSign) {
throw new Error('WASM function not available');
}
const signature = globalThis.genReqSign(query, body, Date.now());
return signature.sign;
}
async function handler(ctx) {
const comic_id = ctx.req.param('comicid').startsWith('mc') ? ctx.req.param('comicid').replace('mc', '') : ctx.req.param('comicid');
const link = `https://manga.bilibili.com/detail/mc${comic_id}`;
const spi_response = await got('https://api.bilibili.com/x/frontend/finger/spi');
const query = 'device=pc&platform=web&nov=25';
const body = JSON.stringify({
comic_id: Number(comic_id),
});
View on GitHub (pinned to bed535e087)
Solutions
- Clear the cached WASM: flush/clear the Redis or in-memory cache entry 'bilibili-manga-wasm-20250208' so it re-downloads.
- Check if the hardcoded WASM URL (https://s1.hdslb.com/bfs/manga-static/manga-pc/6732b1bf426cfc634293.wasm) still resolves — if Bilibili changed it, update the URL and cache key in the source.
- Verify the downloaded buffer is actually WASM (starts with magic bytes 0x00 0x61 0x73 0x6d) and not an HTML error page.
- Ensure the Node.js version supports the WASM module (use Node 18+).
Example fix
// before: hardcoded URL and cache key that may go stale
const wasmResp = await got('https://s1.hdslb.com/bfs/manga-static/manga-pc/6732b1bf426cfc634293.wasm', {...});
// after: validate the buffer is real WASM before instantiating
const wasmBuffer = Buffer.from(wasmResp.data);
if (wasmBuffer.length < 8 || wasmBuffer[0] !== 0x00 || wasmBuffer[1] !== 0x61) {
throw new Error('Downloaded WASM is invalid (got non-WASM content). URL may be stale.');
} Defensive patterns
Strategy: validation
Validate before calling
// Validate the WASM buffer before relying on it
const wasmBuffer = Buffer.from(wasmBufferBase64, 'base64');
const WASM_MAGIC = [0x00, 0x61, 0x73, 0x6d];
const isValidWasm = wasmBuffer.length >= 4 &&
WASM_MAGIC.every((byte, i) => wasmBuffer[i] === byte);
if (!isValidWasm) {
throw new Error('Invalid WASM buffer — URL may be stale or CDN returned an error page');
} Type guard
function isValidWasmBuffer(buf: Buffer): boolean {
return buf.length >= 4 &&
buf[0] === 0x00 && buf[1] === 0x61 &&
buf[2] === 0x73 && buf[3] === 0x6d;
}
function isGenReqSignAvailable(): boolean {
return typeof globalThis.genReqSign === 'function';
} Try / catch
try {
const { instance } = await WebAssembly.instantiate(wasmBuffer, go.importObject);
go.run(instance);
if (typeof globalThis.genReqSign !== 'function') {
throw new Error('WASM instantiated but genReqSign not found — binary may be stale');
}
} catch (e) {
logger.error(`WASM init failed: ${e.message}. Clearing cache.`);
await cache.delete?.('bilibili-manga-wasm-20250208');
throw e;
} Prevention
- Clear the WASM cache entry when the CDN URL changes.
- Validate the WASM magic bytes after download.
- Update the hardcoded WASM URL when Bilibili rotates it.
- Use a versioned cache key that matches the WASM file hash.
When it happens
Trigger: WebAssembly.instantiate succeeds (or partially succeeds) but go.run(instance) does not register genReqSign on globalThis. Causes: the cached WASM buffer (key 'bilibili-manga-wasm-20250208') is stale/corrupted, the CDN URL returns an HTML error page instead of WASM, the Go WASM runtime version is incompatible, or Node.js lacks full WebAssembly support.
Common situations: Bilibili updated the WASM file (new hash/URL) but the cache key still holds the old binary; the CDN URL in the source is hardcoded and Bilibili moved the file; network proxy returned an error page that was cached as the WASM; Node.js version too old for the WASM features used.
Related errors
- 缺少对应 uid 的 Bilibili 用户登录后的 Cookie 值
- 对应 uid 的 Bilibili 用户的 Cookie 已过期
- Category not found
- Tag not found
- 缺少对应 uid 的 Bilibili 用户登录后的 Cookie 值
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/01776faab0607071.
Report an issue: GitHub.