binary-husky/gpt_academic · error · Exception

Cannot convert response {i} to string

Error message

Cannot convert response {i} to string

What it means

Raised in QueryAnalyzer when a multi-prompt LLM response object cannot be coerced to a string with str(). The analyzer sends N prompts through a multiplexed request and reads responses at odd indices (i*2+1); if the element at that slot is a non-string object whose __str__ raises (or str() is intercepted by a bare except), this exception aborts the whole query analysis. It is effectively a data-shape error on the LLM client's return list.

Source

Thrown at crazy_functions/paper_fns/auto_git/query_analyzer.py:223

                llm_kwargs=llm_kwargs,
                chatbot=chatbot,
                history_array=[[] for _ in prompts],
                sys_prompt_array=sys_prompts,
                max_workers=3
            )

            # 从收集的响应中提取我们需要的内容
            extracted_responses = []
            for i in range(len(prompts)):
                if (i * 2 + 1) < len(responses):
                    response = responses[i * 2 + 1]
                    if response is None:
                        raise Exception(f"Response {i} is None")
                    if not isinstance(response, str):
                        try:
                            response = str(response)
                        except:
                            raise Exception(f"Cannot convert response {i} to string")
                    extracted_responses.append(response)
                else:
                    raise Exception(f"未收到第 {i + 1} 个响应")

            # 解析基本信息
            query_type = self._extract_tag(extracted_responses[self.BASIC_QUERY_INDEX], "query_type")
            if not query_type:
                print(
                    f"Debug - Failed to extract query_type. Response was: {extracted_responses[self.BASIC_QUERY_INDEX]}")
                raise Exception("无法提取query_type标签内容")
            query_type = query_type.lower()

            main_topic = self._extract_tag(extracted_responses[self.BASIC_QUERY_INDEX], "main_topic")
            if not main_topic:
                print(f"Debug - Failed to extract main_topic. Using query as fallback.")
                main_topic = query

            query_type = self._normalize_query_type(query_type, query)

View on GitHub (pinned to d6bde0fa54)

Solutions

  1. Inspect the actual type of responses[i*2+1] by logging repr(type(response)) before conversion
  2. If responses come from a request_multiplexer-style helper, verify it returns [prompt, response, prompt, response, ...] pairs of plain strings
  3. Replace the bare except with 'except Exception as e' and include e in the message so the root cause is visible
  4. Normalize upstream: have the LLM client layer always return str or raise before results reach the analyzer

Example fix

// before
if not isinstance(response, str):
    try:
        response = str(response)
    except:
        raise Exception(f"Cannot convert response {i} to string")

// after
if not isinstance(response, str):
    try:
        response = str(response)
    except Exception as e:
        raise Exception(f"Cannot convert response {i} (type={type(response).__name__}) to string: {e}")
Defensive patterns

Strategy: validation

Validate before calling

def validate_responses(prompts, responses):
    if len(responses) < len(prompts) * 2:
        raise ValueError(f"responses too short: {len(responses)} < {len(prompts)*2}")
    for i in range(len(prompts)):
        r = responses[i*2 + 1]
        if r is None:
            raise ValueError(f"response {i} is None")
        try:
            str(r)
        except Exception as e:
            raise ValueError(f"response {i} of type {type(r).__name__} not str-able: {e}")

Type guard

def is_str_response(r) -> bool:
    return isinstance(r, str) or (r is not None and not isinstance(r, BaseException))

Try / catch

try:
    analysis = analyzer.analyze(query)
except Exception as e:
    if "Cannot convert response" in str(e):
        logger.error("LLM returned non-string payload; check backend client")
    raise

Prevention

When it happens

Trigger: Calling the analyze pipeline where responses[i*2+1] is an exception object, a dict, or a custom object with a broken __str__/__repr__; the bare 'except:' around str(response) swallows the real exception and re-raises this generic message.

Common situations: Switching LLM backends that return tuples/dicts instead of plain strings; a downstream library raising inside __str__ (e.g. lazy generator already consumed); None checks passed but error objects leaked into the response list.

Related errors


AI-assisted analysis of binary-husky/gpt_academic@d6bde0fa54 (2026-08-14). Data as JSON: /api/errors/40adea09588a4407. Report an issue: GitHub.