{"record":{"id":"2075fcc6289dc3e9","repo":"langflow-ai/langflow","slug":"metadata-array-key-exceeds-kb-metadata-max-ar","errorCode":null,"errorMessage":"Metadata array '{key}' exceeds {KB_METADATA_MAX_ARRAY_LENGTH} items.","messagePattern":"Metadata array '(.+?)' exceeds (.+?) items\\.","errorType":"validation","errorClass":"HTTPException","httpStatus":422,"severity":"warning","filePath":"src/backend/base/langflow/api/utils/kb_metadata.py","lineNumber":53,"sourceCode":"\ndef _is_valid_key(key: str) -> bool:\n    if not key or len(key) > KB_METADATA_MAX_KEY_LENGTH:\n        return False\n    return all(c in _KEY_ALLOWED_CHARS for c in key)\n\n\ndef _validate_value(key: str, value: Any) -> None:\n    if isinstance(value, (bool, int, float)):\n        return\n    if isinstance(value, str):\n        if len(value) > KB_METADATA_MAX_VALUE_LENGTH:\n            msg = f\"Metadata value for '{key}' exceeds {KB_METADATA_MAX_VALUE_LENGTH} characters.\"\n            raise HTTPException(status_code=422, detail=msg)\n        return\n    if isinstance(value, list):\n        if len(value) > KB_METADATA_MAX_ARRAY_LENGTH:\n            msg = f\"Metadata array '{key}' exceeds {KB_METADATA_MAX_ARRAY_LENGTH} items.\"\n            raise HTTPException(status_code=422, detail=msg)\n        for entry in value:\n            if not isinstance(entry, str):\n                msg = f\"Metadata array '{key}' must contain only strings.\"\n                raise HTTPException(status_code=422, detail=msg)\n            if len(entry) > KB_METADATA_MAX_VALUE_LENGTH:\n                msg = f\"Metadata array entry under '{key}' exceeds {KB_METADATA_MAX_VALUE_LENGTH} characters.\"\n                raise HTTPException(status_code=422, detail=msg)\n        return\n    msg = f\"Metadata value for '{key}' must be a string, number, bool, or string array; got {type(value).__name__}.\"\n    raise HTTPException(status_code=422, detail=msg)\n\n\ndef validate_user_metadata(metadata: dict[str, Any]) -> dict[str, Any]:\n    \"\"\"Enforce the user-metadata contract on a decoded dict.\n\n    Returns the same dict (a shallow copy is *not* made — callers may mutate\n    safely once validation passes). Raises :class:`HTTPException` with a 422\n    status on any violation so FastAPI surfaces an inline error.","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/langflow-ai/langflow/blob/976ec789d2886a86de109c044d089d68e96c9a35/src/backend/base/langflow/api/utils/kb_metadata.py#L35-L71","documentation":"Metadata validation caps list-valued metadata at KB_METADATA_MAX_ARRAY_LENGTH = 16 items. Arrays are allowed only as lists of short strings; a longer list is rejected with 422 because array metadata is replicated onto every chunk of the ingested file, multiplying storage in the vector store.","triggerScenarios":"A multipart ingest request where the metadata JSON contains an array with 17+ entries, e.g. {\"tags\": [\"a\",\"b\",... 20 items]}, either at run level (metadata field) or inside per_file_metadata. The length check runs before per-entry type/length checks, so an oversize array of valid strings still fails here first.","commonSituations":"Tag/category taxonomies imported from another system with dozens of labels per document; keyword extraction pipelines emitting unbounded tag lists; teams expecting tags to scale like a documents table rather than per-chunk metadata.","solutions":["Keep any single array <=16 items — take the top-N tags (e.g. by score/frequency) client-side.","Split an oversized tag list into multiple metadata keys (tags_1, tags_2, ...) if truly needed — still respecting the 16-key overall limit.","If more tags are genuinely required, store them in your own index keyed by file id and keep only coarse tags in KB metadata.","Check KB_METADATA_MAX_ARRAY_LENGTH in langflow.utils.kb_constants before submitting so the client and server agree."],"exampleFix":"# before\nmetadata = {\"tags\": all_tags}  # 40 tags -> 422\n\n# after\nMAX_ARRAY = 16\nmetadata = {\"tags\": sorted(all_tags, key=score, reverse=True)[:MAX_ARRAY]}","handlingStrategy":"validation","validationCode":"from langflow.utils.kb_constants import KB_METADATA_MAX_ARRAY_LENGTH as MAXA\n\ndef cap_arrays(meta: dict) -> dict:\n    return {k: (v[:MAXA] if isinstance(v, list) else v) for k, v in meta.items()}","typeGuard":"def is_valid_array(v) -> bool:\n    return not isinstance(v, list) or len(v) <= 16","tryCatchPattern":"try:\n    validate_user_metadata(meta)\nexcept HTTPException as e:\n    if e.status_code == 422 and 'exceeds' in e.detail and 'items' in e.detail:\n        meta = {k: (v[:16] if isinstance(v, list) else v) for k, v in meta.items()}\n        validate_user_metadata(meta)\n    else:\n        raise","preventionTips":["Take top-N tags client-side rather than shipping full taxonomies.","Split very long lists across multiple keys only if the 16-key cap allows.","Re-check array lengths whenever a taxonomy grows."],"tags":["knowledge-base","metadata","validation","http-422","limits"],"backgroundTag":null,"analyzedSha":"976ec789d2886a86de109c044d089d68e96c9a35","analyzedAt":"2026-08-14T18:23:12.227Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}