Skip to content

fix(rag): Unknown knowledge-database configuration keys are silently accepted and stored #1850

Description

@tandau-bbv

The Form-duality contract introduced by #1822 promises that a knowledge database's configuration is validated against the form its ingestor announced. Validation of declared fields works, but fields the ingestor never declared pass straight through and are persisted, so a mistyped knob is accepted, stored and silently ignored at ingestion time. Found while end-to-end verifying #1841.

Current behaviour: POST /knowledge/databases/{database} accepts a configuration containing keys no announced form element declares, and writes them verbatim into BucketEntity.configuration. IngestorConfig sets extra="allow" (packages/core/swiss_ai_hub/core/ingestors/ingestor_config.py:28), so the model built by ModelCreationService.create_config_model and checked by InstanceConfigHelper.validate_config_for_create (packages/api/swiss_ai_hub/api/routes/knowledge/knowledge_service.py:455-457) retains unrecognised fields rather than rejecting them.

Required fields are still caught — a typo that omits llm_model correctly fails with llm_model: Field required. The gap is optional knobs: the three enrichment flags, vision_model, and any optional field a custom pipeline declares.

Expected behaviour: a configuration carrying a field the ingestor's announced form does not declare is rejected with a 400 naming that field, matching #1822's acceptance criterion.

Repro:

  1. Create a database with a typo on an optional flag and an optional model:
POST /api/v1/{tenant}/knowledge/databases/kbtypo
{"ingestor":"document_ingestion","configuration":{
  "name":{"en":"Typo"},"description":{"en":"d"},
  "llm_model":"text-generation/Kimi-K2.6","embedding_model":"embedding/bge-m3",
  "with_table_refinemnt":false, "vision_modl":"text-generation/MinerU2.5-2509-1.2B"}}
  1. Observed: HTTP 200, and the row stores both misspelled keys.
  2. The pipeline then resolves the defaults for the fields the user meant to set:
user typed with_table_refinemnt=false  ->  actual with_table_refinement = True
user typed vision_modl=MinerU...       ->  actual vision model          = text-generation/Kimi-K2.6

The user believes they disabled an expensive enrichment step and chose a vision model; neither took effect, and the stored configuration looks deliberate. The same permissiveness lets one ingestor's knobs be submitted to another (crawl_depth from a custom ingestor is accepted by document_ingestion), weakening the per-ingestor isolation #1822 claims.

In scope

  • Reject a knowledge-database configuration that carries fields the database's ingestor did not announce, with a 400 naming the offending field.
  • Keep the existing behaviour for rows already stored: a database created before this fix, or whose pipeline has since dropped a field, must keep resolving and ingesting unchanged.

Out of scope

  • The same extra="allow" on AgentConfig (packages/core/swiss_ai_hub/core/agents/agent_config.py:98), which likely lets agent instances accept undeclared config keys too. The Form stack is shared, so a fix here may generalise — but the agent/process surface needs its own verification and issue rather than being changed blind.
  • Capability filtering of the vision-model picker — see Capability- and location-aware model selection for agents #1769 (sibling).
  • The retriever honouring configuration["embedding_model"] — see feat(rag): Retriever reads the embedding model from the knowledge database #1820 (sibling).
  • Any path to edit a stored configuration after creation; today there is none, so this issue only concerns the create path.

Accepted when

  • Creating a knowledge database with a misspelled optional field is refused, and the message names that field.
  • Creating a knowledge database with a field belonging to a different ingestor is refused.
  • A valid configuration for the database's own ingestor is still accepted, including omitted optional fields.
  • Databases created before the fix continue to ingest with their stored configuration, unchanged.
  • make test passes in the affected scopes.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:apipackages/api — FastAPIarea:pipelinepackages/pipeline — Pipelines / Dagsterpatch

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions