Repository navigation
Description
Contact Information
No response
MaxKB Version
v2 branch, commit 2900bd8
Problem Description
Many serializer fields check an enum with a pattern like ^embedding|keywords|blend$. In regex, | splits the whole pattern. So this means ^embedding OR keywords OR blend$. Django's RegexValidator uses search, so any value that starts with embedding, contains keywords, or ends with blend is accepted. xkeywords, keywordsx and not_keywords_valid all pass.
The same shape is in 16 places across 10 files:
- search_mode:
apps/application/chat_pipeline/step/search_dataset_step/i_search_dataset_step.py,apps/application/flow/step_node/search_knowledge_node/i_search_knowledge_node.py,apps/application/serializers/application.py,apps/knowledge/serializers/knowledge.py(two places) - application type
^SIMPLE|WORK_FLOW$, comparer^and|or$, hit_handling_method, export type^csv|excel$, sync type^replace|complete$ - tool node input
typeandsource(i_tool_node.py), trigger inputsource - valid_type
^application|knowledge|user$inapps/system_manage/serializers/valid_serializers.py - email code type
^register|reset_password$inapps/users/serializers/user.py(two places)
ToolInputField in apps/tools/serializers/tool.py has the same two patterns. Nothing references that class, so I left it alone.
The bad value is used later. For example search_mode goes to SearchMode(search_mode) and raises ValueError: 'xkeywords' is not a valid SearchMode. valid_type goes to model_message_dict.get(valid_type), which returns None, and then .get('count') raises AttributeError. Both give a 500 instead of a 400 with the validator message.
Steps to Reproduce
import re
re.compile("^embedding|keywords|blend$").search("xkeywords") # matches, so the validator accepts it
re.compile("^(embedding|keywords|blend)$").search("xkeywords") # NoneI put each of the 16 patterns in a DRF CharField with RegexValidator, like the real serializers. I compared the current patterns with the grouped ones using 57,668 cases per side. The cases were neighbor values, 3,000 mutations of each valid value per pattern, and random strings. The current patterns wrongly accepted 12,445 of them. The grouped patterns accepted 0, and no valid value was rejected. A Hypothesis property with 3,000 examples also passed. A DRF serializer with the same patterns accepts search_mode=xkeywords and valid_type=xuser before the fix and returns 400 after it.
I did not run the full app (it needs Postgres and Redis). So the 500 is shown on the same classes and dict, not through the HTTP route.
The expected correct result
Only the exact values pass, for example embedding, keywords and blend. Anything else gets a 400 with the validator message.
Related log output
ValueError: 'xkeywords' is not a valid SearchModeAdditional Information
Fix: Wrap the alternation in a group: ^(embedding|keywords|blend)$. Same change for every pattern. The set of allowed values stays the same. I will open a PR.
valid_type allows knowledge, but model_message_dict in valid_serializers.py has the key dataset, not knowledge. So valid/knowledge/50 still gives None.get and a 500, before and after this change. No UI code calls it with knowledge. This is a separate bug. I can open another issue if you want.
Validated with Claude Opus 5.5.
Activity