fish2018/pansou · error

入口脚本未找到搜索接口标识

Error message

入口脚本未找到搜索接口标识

What it means

After locating the search route in the entry bundle, the plugin looks backwards up to 2048 bytes for hash-like identifiers (hashPattern) that encode the server function ID. If none are found it returns this error, because the server function ID needed to call the search API could not be extracted.

Solutions

  1. Inspect the bundle around the route string and update hashPattern to the new identifier format.
  2. Widen the 2048-byte window (or search the whole bundle) if the hash is simply farther from the route literal.
  3. If the ID moved to a manifest/build-metadata file, fetch and parse that file instead.
  4. Upgrade the plugin to a version compatible with the current site build.

Example fix

// before
windowStart := max(0, routeIndex-2048)
hashes := hashPattern.FindAll(assetBody[windowStart:routeIndex], -1)
// after
windowStart := max(0, routeIndex-16384)
hashes := hashPattern.FindAll(assetBody[windowStart:routeIndex], -1)
Defensive patterns

Strategy: validation

Validate before calling

window := assetBody[max(0, routeIndex-16384):routeIndex]
if len(hashPattern.FindAll(window, -1)) == 0 {
	log.Printf("no function-ID hash near route; pattern needs update")
}

Type guard

func hasFunctionIDHash(body []byte, routeIndex int) bool {
	window := body[max(0, routeIndex-2048):routeIndex]
	return len(hashPattern.FindAll(window, -1)) > 0
}

Try / catch

funcID, err := discoverServerFunctionID(ctx, req)
if err != nil && strings.Contains(err.Error(), "入口脚本未找到搜索接口标识") {
	log.Printf("hash pattern outdated: %v", err)
	return nil, errSkipPlugin
}

Prevention

When it happens

Trigger: hashPattern.FindAll over the 2048-byte window before "/s/$query" yields zero matches: the bundle layout changed so the hash is farther away, in a different format, or generated at runtime.

Common situations: Bundler upgrade changed chunk hashing/format or moved the function ID reference beyond the 2048-byte window; the ID is now fetched from a separate manifest file; minification altered identifier shape.

Related errors


AI-assisted analysis of fish2018/pansou@beaa561337 (2026-09-07). Data as JSON: /api/errors/275cf5379ed019d8. Report an issue: GitHub.

Appendix: source

Thrown at plugin/xiaokupan/xiaokupan.go:258

	assetReq, err := http.NewRequestWithContext(ctx, http.MethodGet, strings.TrimRight(p.baseURL, "/")+assetPath, nil)
	if err != nil {
		return "", err
	}
	assetReq.Header.Set("User-Agent", req.Header.Get("User-Agent"))
	assetReq.Header.Set("Referer", homeURL)
	assetBody, err := doLimitedRequest(client, assetReq, maxDiscoveryBodySize)
	if err != nil {
		return "", fmt.Errorf("读取入口脚本失败: %w", err)
	}

	routeIndex := strings.Index(string(assetBody), "/s/$query")
	if routeIndex < 0 {
		return "", fmt.Errorf("入口脚本未找到搜索路由")
	}
	windowStart := max(0, routeIndex-2048)
	hashes := hashPattern.FindAll(assetBody[windowStart:routeIndex], -1)
	if len(hashes) == 0 {
		return "", fmt.Errorf("入口脚本未找到搜索接口标识")
	}
	return string(hashes[len(hashes)-1]), nil
}

func parseSearchResponse(body []byte) ([]model.SearchResult, error) {
	var root serovalNode
	if err := stdjson.Unmarshal(body, &root); err != nil {
		return nil, fmt.Errorf("解析 Seroval 响应失败: %w", err)
	}
	decoder := newSerovalDecoder(&root)
	resultNode := decoder.objectValue(&root, "result")
	searchResultsNode := decoder.objectValue(resultNode, "searchResults")
	mergedNode := decoder.objectValue(searchResultsNode, "merged_by_type")
	mergedNode = decoder.resolve(mergedNode)
	if mergedNode == nil || mergedNode.Props == nil {
		return nil, fmt.Errorf("响应缺少 merged_by_type")
	}

View on GitHub (pinned to beaa561337)