datawhalechina/hello-agents · error · Exception

Unknown relation type

Error message

Unknown relation type '{relation}'.

What it means

find_fact(relation) validates its argument against self.predicate_to_fact_instances, a dict grouping currently-known facts by predicate name (e.g. 'Parallel', 'Perpendicular', 'Eq'). Passing a relation string that is not a key raises this Exception. Note the logic bug: the emptiness check 'if len(self.predicate_to_fact_instances) == 0' comes after the membership check, so an unknown relation raises even when the fact table is empty instead of returning the friendly 'list is empty' message.

Solutions

  1. Enumerate valid relations first: valid = sorted(solver.predicate_to_fact_instances.keys()) and pass one of those exactly.
  2. Match the casing used by the GDL predicates (typically capitalized like 'Parallel').
  3. If the dict is empty, add/derive facts before querying — the 'empty' friendly path is unreachable for unknown names due to the check order.

Example fix

# before
solver.find_fact('parallel')  # wrong casing -> raises

# after
valid = sorted(solver.predicate_to_fact_instances.keys())
rel = next((r for r in valid if r.lower() == 'parallel'), None)
print(solver.find_fact(rel) if rel else f'no such relation, have {valid}')
Defensive patterns

Strategy: validation

Validate before calling

def safe_find_fact(solver, relation):
    keys = solver.predicate_to_fact_instances.keys()
    match = next((k for k in keys if k.lower() == relation.lower()), None)
    if match is None:
        return f'unknown relation; valid: {sorted(keys)}'
    return solver.find_fact(match)

Try / catch

try:
    print(solver.find_fact(relation))
except Exception as e:
    if str(e).startswith("Unknown relation type"):
        print('valid relations:', sorted(solver.predicate_to_fact_instances))

Prevention

When it happens

Trigger: Calling solver.find_fact('paralle') (typo), find_fact('parallel') with wrong casing, or a predicate that simply has no facts recorded yet in a fresh problem state — the membership check fires before any content check.

Common situations: Agents guessing predicate names not present in the current problem's fact table; casing/naming mismatches between GDL predicates and the relation string; querying before any facts were added or derived.

Related errors


AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14). Data as JSON: /api/errors/0ce9fbf24ee7423c. Report an issue: GitHub.

Appendix: source

Thrown at Co-creation-projects/BitSecret-GPSAgent/src/gps/symbolic_solver.py:1409

        all_goal_ids = set()
        for father_id in father_ids:  # add sub_goals
            operation_id = self._add_operation(('Decompose', theorem_name, theorem_paras))
            goal_ids = self._add_goals(sub_goals, father_id, operation_id)
            if goal_ids is not None:
                all_goal_ids.update(goal_ids)

        if len(all_goal_ids) == 0:
            return f"使用定理'{theorem}'分解目标{goal}失败,新分解的子目标不能是原目标的父目标。"

        self._check_goals(all_goal_ids)

        result = f"使用定理'{theorem}'分解目标{goal}成功,以下为问题的状态更新。\n"
        return result + self._get_update(old_fact_id, old_goal_id, old_goal_status)

    def find_fact(self, relation):
        if relation not in self.predicate_to_fact_instances:
            msg = f"Unknown relation type '{relation}'."
            raise Exception(msg)

        if len(self.predicate_to_fact_instances) == 0:
            return relation + f"类型的关系列表为空,当前问题暂时未推导出{relation}关系。"

        if relation == 'Eq':
            result = []
            if len(self.equations) > 0:
                result.append("按照方程变量是否相交来分组,得到的代数方程组(所有方程省略'=0'、组序号可能不连续):")
                for group_id in self.equations:
                    eqs = [str(eq).replace(' ', '') for eq in self.equations[group_id][0]]
                    result.append(f'Group {group_id}: ' + ', '.join(eqs))
            if len(self.sym_to_value) > 0:
                result.append("以下是所有已经求解出值的变量:")
                result.append(str(self.sym_to_value))
            return '\n'.join(result)
        else:
            instances = []
            for instance in self.predicate_to_fact_instances[relation]:

View on GitHub (pinned to 606a07d341)