fish2018/pansou · error

未能验证credential_action_id

Error message

未能验证credential_action_id

What it means

During Action ID discovery none of the potential IDs validated as the credential_action_id: for every candidate, the credential-verification probe failed, so credentialIDFound stayed false. The plugin cannot identify which candidate ID is used to mint search credentials.

Solutions

  1. Clear the action ID cache and re-run discovery so a fresh candidate set is extracted.
  2. Enable DebugLog and watch each candidate's verification result to see whether probes errored or merely failed validation.
  3. curl the credential endpoint manually with a candidate ID to confirm the expected response shape.
  4. Update the plugin if the upstream ID scheme changed.
Defensive patterns

Strategy: retry

Try / catch

ids, err := plugin.DiscoverActionIDs()
if err != nil && strings.Contains(err.Error(), "未能验证credential_action_id") {
    time.Sleep(retryDelay)
    ids, err = plugin.DiscoverActionIDs() // fresh candidate set
}

Prevention

When it happens

Trigger: Running discoverActionIDs (via doSearch or getOrDiscoverActionIDs) when none of the extracted candidate IDs is accepted by the credential endpoint — upstream changed which ID is used, all candidates are stale, or the verification call itself failed for each candidate.

Common situations: Upstream rotated/renamed its embedded Action IDs; site deployed a new obfuscation scheme; transient network errors caused every verification attempt to fail; IP blocked by the site.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at plugin/panyq/panyq.go:478

				credIDChan <- actionID
			}
		}(i, id)
	}
	
	// 等待所有验证完成
	wg.Wait()
	close(credIDChan)
	
	// 从通道中获取第一个有效ID
	var credentialIDFound bool
	for id := range credIDChan {
		finalIDs[ActionIDKeys[0]] = id
		credentialIDFound = true
		break
	}
	
	if !credentialIDFound {
		return nil, fmt.Errorf("未能验证credential_action_id")
	}
	
	// 获取测试凭证用于后续验证
	testCreds, err := p.getCredentials("test", finalIDs[ActionIDKeys[0]], p.client)
	if err != nil {
		return nil, fmt.Errorf("获取测试凭证失败: %w", err)
	}
	
	if DebugLog {
		fmt.Printf("panyq: 获取到测试凭证: sign=%.10s..., hash=%.10s..., sha=%.10s...\n", 
			testCreds.Sign, testCreds.Hash, testCreds.Sha)
	}
	
	// 从剩余ID中排除已使用的ID
	remainingIDs := make([]string, 0, len(potentialIDs)-1)
	for _, id := range potentialIDs {
		if id != finalIDs[ActionIDKeys[0]] {
			remainingIDs = append(remainingIDs, id)

View on GitHub (pinned to beaa561337)