666ghj/MiroFish · error · ValueError
Ontology result must be an object
Error message
Ontology result must be an object
What it means
Raised in OntologyGenerator._validate_and_process when the parsed LLM response for ontology generation is not a JSON object (dict). The generator asks the LLM for a JSON object with entity_types/edge_types/analysis_summary; if parsing yields a list, a bare string, or null (e.g. the model returned a JSON array, a markdown-fenced scalar, or empty content), this ValueError fires before any field extraction.
Source
Thrown at backend/app/services/ontology_generator.py:435
"""长分块保留首尾,避免每个分块内部再次变成只看开头。"""
text = text.strip()
if len(text) <= char_limit:
return text
marker = "\n...(本分块中间内容省略)...\n"
if char_limit <= len(marker) + 20:
return text[:char_limit]
remaining = char_limit - len(marker)
head_len = remaining // 2
tail_len = remaining - head_len
return f"{text[:head_len].rstrip()}{marker}{text[-tail_len:].lstrip()}"
def _validate_and_process(self, result: Dict[str, Any]) -> Dict[str, Any]:
"""验证和后处理结果"""
if not isinstance(result, dict):
raise ValueError("Ontology result must be an object")
raw_entities = result.get("entity_types")
raw_edges = result.get("edge_types")
if not isinstance(raw_entities, list):
raw_entities = []
if not isinstance(raw_edges, list):
raw_edges = []
if not isinstance(result.get("analysis_summary"), str):
result["analysis_summary"] = ""
# Normalize entity entries before touching their fields. LLMs
# occasionally emit a bare string, null, or another scalar.
entity_name_map: Dict[str, str] = {}
processed_entities: List[Dict[str, Any]] = []
seen_entity_names = set()
for raw_entity in raw_entities:
if isinstance(raw_entity, str):
entity = {"name": raw_entity}View on GitHub (pinned to b5b53acc57)
Solutions
- Retry generation with the same prompt — non-dict output is often stochastic; add explicit 'respond with a single JSON object' instruction and an example in the prompt.
- If the model consistently returns a list, wrap/normalize: accept a top-level list by mapping it to {"entity_types": result} if that matches intent.
- Increase max_tokens to avoid truncation, and use JSON mode / response_format=json_object when the provider supports it.
- Log the raw LLM output on failure to see exactly which shape the model emitted before patching.
Example fix
# before
result = json.loads(raw)
processed = gen._validate_and_process(result)
# after
result = json.loads(raw)
if isinstance(result, list):
result = {"entity_types": result}
processed = gen._validate_and_process(result) Defensive patterns
Strategy: type-guard
Type guard
def is_ontology_object(result: object) -> bool:
return isinstance(result, dict) Try / catch
result = parse_llm_json(raw)
if not isinstance(result, dict):
if isinstance(result, list):
result = {"entity_types": result} # normalize observed LLM shape
else:
result = regenerate_with_stricter_prompt() # one retry, then fail
processed = gen._validate_and_process(result) Prevention
- Request JSON mode / response_format=json_object when the provider supports it.
- Include a concrete JSON-object example in the prompt.
- Log raw LLM output on validation failure to spot schema drift early.
When it happens
Trigger: LLM returns a JSON array of entities instead of an object; model outputs prose or a code block whose parsed JSON is a scalar; response truncated so the parser produced a non-dict fragment; weaker model ignoring the schema prompt.
Common situations: Switching to a smaller/cheaper model that ignores output-format instructions; prompts edited so the requested shape drifted; max_tokens set too low causing truncation and salvage-parsing; some providers returning top-level arrays by convention.
Related errors
- LLM JSON output was truncated at the token limit
- LLM JSON generation stopped unexpectedly ({finish_reason})
- LLM returned empty JSON content
- LLM returned invalid JSON (line {strict_error.lineno}, colum
- LLM returned multiple JSON values
AI-assisted analysis of 666ghj/MiroFish@b5b53acc57 (2026-08-14).
Data as JSON: /api/errors/69bdc58b349b6a75.
Report an issue: GitHub.