{"record":{"id":"245c0fe1630f3338","repo":"cocoindex-io/cocoindex","slug":"row-row-id-r-missing-vector-fields-sorted-miss","errorCode":null,"errorMessage":"Row {row.id!r}: missing vector fields {sorted(missing)}.","messagePattern":"Row (.+?): missing vector fields (.+?)\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/cocoindex/connectors/turbopuffer/_target.py","lineNumber":208,"sourceCode":"\ndef _vector_to_list(v: Sequence[float] | np.ndarray) -> list[float]:\n    if isinstance(v, np.ndarray):\n        return v.tolist()  # type: ignore[no-any-return]\n    return list(v)\n\n\ndef _row_to_upsert(row: Row, schema: NamespaceSchema) -> dict[str, Any]:\n    \"\"\"Convert a Row to the dict shape turbopuffer's write API expects.\"\"\"\n    out: dict[str, Any] = {\"id\": row.id}\n\n    if isinstance(schema.vectors, _ResolvedNamedVectorsDef):\n        vector_field_names = set(schema.vectors.vectors)\n        if not isinstance(row.vector, dict):\n            raise ValueError(\n                f\"Row {row.id!r}: schema declares named vectors \"\n                f\"({sorted(vector_field_names)}) but row.vector is not a dict.\"\n            )\n        missing = vector_field_names - set(row.vector)\n        if missing:\n            raise ValueError(\n                f\"Row {row.id!r}: missing vector fields {sorted(missing)}.\"\n            )\n        for name, vec in row.vector.items():\n            out[name] = _vector_to_list(vec)\n    else:\n        vector_field_names = {_DEFAULT_VECTOR_FIELD}\n        if isinstance(row.vector, dict):\n            raise ValueError(\n                f\"Row {row.id!r}: schema declares a single unnamed vector but \"\n                f\"row.vector is a dict.\"\n            )\n        out[_DEFAULT_VECTOR_FIELD] = _vector_to_list(row.vector)\n\n    reserved = {\"id\"} | vector_field_names\n    if row.attributes:\n        for k, v in row.attributes.items():","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/cocoindex-io/cocoindex/blob/e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b/python/cocoindex/connectors/turbopuffer/_target.py#L190-L226","documentation":"For a named-vectors turbopuffer schema, every declared vector field must be present in `row.vector`. `_row_to_upsert` computes `vector_field_names - set(row.vector)`; if any declared field is absent it raises this ValueError listing the missing names. Turbopuffer's write API needs a value for each declared vector, so partial dicts are rejected client-side.","triggerScenarios":"Schema declares vectors {\"title_vec\", \"body_vec\"} but Row is built as Row(id=..., vector={\"title_vec\": [...]}) — the 'body_vec' key is missing when reconcile serializes the row.","commonSituations":"Adding a new vector field to the schema without updating row-building code; computing one embedding lazily and omitting the key on failure; a typo in a dict key so the declared name isn't matched.","solutions":["Include an entry for every declared vector field in the row.vector dict, using the exact names from sorted(schema.vectors.vectors).","Fix key typos by copying names from the error message or schema definition rather than typing them by hand.","If the field is optional for this row, provide a zero/dummy vector of the declared size, or restructure the schema so that field is a separate namespace."],"exampleFix":"// before\nRow(id=1, vector={\"title_vec\": embed(title)})\n\n// after\nRow(id=1, vector={\"title_vec\": embed(title), \"body_vec\": embed(body)})","handlingStrategy":"validation","validationCode":"declared = set(schema.vectors.vectors)\nmissing = declared - set(row.vector)\nassert not missing, f\"Row {row.id} missing vector fields: {missing}\"","typeGuard":"def has_all_vector_fields(v: dict, names: set[str]) -> TypeGuard[dict[str, Sequence[float]]]:\n    return names <= set(v)","tryCatchPattern":"try:\n    await component.reconcile(row)\nexcept ValueError as e:\n    m = re.search(r\"missing vector fields \\[(.*)\\]\", str(e))\n    if m:\n        row = fill_missing_fields(row, ast.literal_eval(m.group(1)))\n    else:\n        raise","preventionTips":["Derive the row.vector dict keys programmatically from schema.vectors.vectors, never by hand","When adding a vector field to the schema, update the embedding step for it in the same change","Fail fast in the embedding function: raise early if any declared field gets no embedding"],"tags":["python","vector","missing-field","turbopuffer"],"backgroundTag":"schema-validation-failed","analyzedSha":"e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b","analyzedAt":"2026-09-08T15:59:19.997Z","contentChangedAt":"2026-09-08T15:59:19.997Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}