iflytek/astron-agent · error · CustomException
SPARK_FUNCTION_NOT_CHOICE_ERROR
SPARK_FUNCTION_NOT_CHOICE_ERROR
Error message
Cannot find function_call field in LLM response
What it means
This CustomException (SPARK_FUNCTION_NOT_CHOICE_ERROR) is raised by the iFlytek Spark function-calling client when the final WebSocket frame (header.status == 2) arrives but the model's reply text entry lacks a 'function_call' key. It means Spark answered with plain content instead of selecting one of the supplied functions, so the caller cannot extract a function name/arguments.
Solutions
- Check the frame payload in the tracing span (function_call_recv event) to confirm the final frame really has no function_call field
- Ensure a non-empty, schema-valid functions list is passed to async_call_spark_fc and that descriptions clearly indicate when to call each function
- Rephrase the user prompt so it clearly requests an action the functions can perform, or adjust temperature/top_k
- If a text answer (no function call) is legitimate for your flow, handle the None/missing case instead of treating it as an error
Example fix
// before
name, usage, arguments = await await_spark_fc(user_input, functions)
// after
try:
name, usage, arguments = await await_spark_fc(user_input, functions)
except CustomException as e:
if e.err_code == CodeEnum.SPARK_FUNCTION_NOT_CHOICE_ERROR:
fallback_answer = await plain_chat(user_input)
else:
raise Defensive patterns
Strategy: fallback
Validate before calling
def functions_ready(functions):
return bool(functions) and all(f.get('name') and f.get('description') for f in functions)
if not functions_ready(function_list):
raise ValueError('functions list must be non-empty with name+description') Type guard
def has_function_call(msg: dict) -> bool:
choices = msg.get('payload', {}).get('choices', {}).get('text', [])
return bool(choices) and 'function_call' in choices[0] Try / catch
try:
name, usage, args = await spark_fc.async_call_spark_fc(user_input, span)
except CustomException as e:
if e.err_code == CodeEnum.SPARK_FUNCTION_NOT_CHOICE_ERROR:
name, usage, args = None, None, None
else:
raise Prevention
- Always pass a non-empty, well-described functions list
- Test prompts against the function set before shipping workflows
- Decide explicitly how 'no function chosen' should behave and code that path
- Monitor span traces for repeated no-function-call responses per prompt template
When it happens
Trigger: In _recv_messages/_process_message: header.code == 0, header.status == 2 (final frame), but 'function_call' not in msg['payload']['choices']['text'][0] — i.e. the model chose not to call any function or returned a normal text answer.
Common situations: User prompt doesn't match any registered function; functions array sent empty or malformed; temperature/top_k tuned so the model prefers free text; Spark content filtering stripped the function decision; prompt history nudges the model toward conversational replies.
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
- SPARK_QUICK_REPAIR_ERROR
- SPARK_REQUEST_ERROR
- PERSONALITY_AI_GENERATE_ERROR
- MODEL_CHECK_FAILED
- MODEL_NOT_EXIST
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/249d96bfb9fbdbc7.
Report an issue: GitHub.
Appendix: source
Thrown at core/workflow/infra/providers/llm/iflytek_spark/spark_fc_llm.py:125
if code != 0:
raise CustomException(
err_code=CodeConvert.sparkCode(code),
cause_error=json.dumps(msg, ensure_ascii=False),
)
status = msg["header"]["status"]
llm_service_sid = msg["header"]["sid"]
# Check if it's a quick repair: if the last character of sid is '1', it's a quick repair
if llm_service_sid[-1] == "1":
raise CustomException(
err_code=CodeEnum.SPARK_QUICK_REPAIR_ERROR,
err_msg="Sensitive content detected, LLM did not find function_call field",
cause_error="Sensitive content detected, LLM did not find function_call field",
)
if status != 2:
continue
token_usage = msg["payload"]["usage"]["text"]
if "function_call" not in msg["payload"]["choices"]["text"][0]:
raise CustomException(
err_code=CodeEnum.SPARK_FUNCTION_NOT_CHOICE_ERROR,
err_msg="Cannot find function_call field in LLM response",
cause_error="Cannot find function_call field in LLM response",
)
name = msg["payload"]["choices"]["text"][0]["function_call"]["name"]
arguments = msg["payload"]["choices"]["text"][0]["function_call"][
"arguments"
]
return name, token_usage, arguments
except websockets.ConnectionClosed:
raise CustomException(
err_code=CodeEnum.SPARK_REQUEST_ERROR,
err_msg="WebSocket connection closed",
cause_error="WebSocket connection closed",
)
except Exception as e:
raise CustomException(View on GitHub (pinned to 5e758547a8)