jackwener/OpenCLI · error · Error
Unrecognized A-share symbol: ${input}
Error message
Unrecognized A-share symbol: ${input} What it means
A plain Error (not CliError) thrown by the exported toSecucode() helper in clis/eastmoney/holders.js when a symbol cannot be mapped to an exchange-suffixed secucode. It accepts prefixed codes (e.g. 1.600519 / 0.000001) or bare 6-digit codes: 60/68/90/113/900 → .SH, 4/8/920/83/87 → .BJ, else .SZ. Anything failing both forms — letters, wrong length, unknown prefixes — reaches the throw at holders.js:25.
Source
Thrown at clis/eastmoney/holders.js:25
import { CliError } from '@jackwener/opencli/errors';
/**
* Convert a bare A-share symbol to eastmoney's SECUCODE form ("600519.SH").
* Accepts "600519", "sh600519", "sz000001", "bj430047", or full "600519.SH".
* @param {string} input
* @returns {string}
*/
function toSecucode(input) {
const raw = String(input || '').trim().toUpperCase();
if (/^\d{6}\.(SH|SZ|BJ)$/.test(raw)) return raw;
const pref = raw.match(/^(SH|SZ|BJ)(\d{6})$/);
if (pref) return `${pref[2]}.${pref[1]}`;
if (/^\d{6}$/.test(raw)) {
if (/^(60|68|90|113|900)/.test(raw)) return `${raw}.SH`;
if (/^(4|8|920|83|87)/.test(raw)) return `${raw}.BJ`;
return `${raw}.SZ`;
}
throw new Error(`Unrecognized A-share symbol: ${input}`);
}
cli({
site: 'eastmoney',
name: 'holders',
access: 'read',
description: '十大流通股东(A股 F10 数据)',
domain: 'datacenter-web.eastmoney.com',
strategy: Strategy.PUBLIC,
browser: false,
args: [
{ name: 'symbol', required: true, positional: true, help: 'A股代码(600519 / sh600519 等)' },
{ name: 'limit', type: 'int', default: 10, help: '返回股东数(默认十大流通股东)' },
],
columns: ['rank', 'reportDate', 'name', 'holdNum', 'floatRatio', 'change'],
func: async (args) => {
/** @type {string} */
let secucode;View on GitHub (pinned to 49907e53dc)
Solutions
- Pass a standard 6-digit A-share code ('600519', '000001', '830799') or prefixed form '1.600519' / '0.000001'.
- Trim and strip stray characters/prefixes from the symbol before calling.
- Route non-A-share symbols to a different data source — toSecucode only handles SH/SZ/BJ.
- Check your code's prefix against the SH/BJ lists; any other 6-digit code falls through to .SZ.
- Validate with /^(\d\.)?\d{6}$/ before calling and emit your own clearer message.
Example fix
// before
const secucode = toSecucode(input); // throws on 'AAPL'
// after
const raw = String(input ?? '').trim().replace(/^(sh|sz|bj)/i, '');
if (!/^(\d\.)?\d{6}$/.test(raw)) throw new CliError('INVALID_ARGUMENT', `Expected 6-digit A-share code, got: ${input}`);
const secucode = toSecucode(raw); Defensive patterns
Strategy: validation
Validate before calling
function normalizeAshareSymbol(input) {
const raw = String(input ?? '').trim();
if (/^\d+\.\d{6}$/.test(raw)) return raw; // 1.600519 form
if (/^\d{6}$/.test(raw)) return raw; // bare code
throw new Error(`Expected A-share symbol (6-digit or N.XXXXXX), got: ${input}`);
} Type guard
/**
* @param {unknown} input
* @returns {input is string}
*/
function isValidAshareSymbol(input) {
if (typeof input !== 'string') return false;
const s = input.trim();
return /^\d+\.\d{6}$/.test(s) || /^\d{6}$/.test(s);
} Try / catch
let secucode;
try {
secucode = toSecucode(input);
} catch (err) {
console.error(`Invalid symbol '${input}': use a 6-digit A-share code (e.g. 600519) or N.XXXXXX form`);
process.exitCode = 1;
return;
} Prevention
- Always pass 6-digit A-share codes or the N.XXXXXX prefixed form to this library.
- Trim and normalize user input (strip 'sh'/'sz' prefixes, whitespace) before calling toSecucode.
- Remember HK/US tickers are unsupported — route them to another data source.
- Know the prefix map: 60/68/90/113/900=SH, 4/8/920/83/87=BJ, other 6-digit=SZ; anything non-conforming throws.
- Unit-test toSecucode against your real symbol set before deploying.
When it happens
Trigger: Calling toSecucode or the holders CLI with 'AAPL', '60051' (5 digits), '6005190' (7 digits), '600.519', an empty string, or HK/US tickers that match neither the `pref` split nor `/^\d{6}$/`.
Common situations: Users passing US/HK tickers instead of A-share codes, using 'sh600519'-style textual prefixes the parser doesn't handle, copy-paste artifacts (whitespace, full-width digits), or genuinely non-A-share instruments.
Related errors
- INVALID_ARGUMENT
- eastmoney convertible returned a malformed response envelope
- eastmoney convertible returned malformed row at rank ${rank}
- INVALID_ARGUMENT
- INVALID_ARGUMENT
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/826ef0e63bc69301.
Report an issue: GitHub.