{"record":{"id":"906748b4e0496d36","repo":"langflow-ai/langflow","slug":"string-must-not-be-empty","errorCode":null,"errorMessage":"String must not be empty.","messagePattern":"String must not be empty\\.","errorType":"validation","errorClass":"ValueError","httpStatus":422,"severity":"error","filePath":"src/backend/base/langflow/api/v1/mappers/deployments/watsonx_orchestrate/payloads.py","lineNumber":41,"sourceCode":"\nif TYPE_CHECKING:\n    from langflow.api.v1.schemas.deployments import DeploymentCreateRequest\n\n# Keep API-boundary scalar normalization local to this module instead of\n# importing adapter-layer aliases, so mapper contracts can evolve independently.\nNormalizedStr = Annotated[\n    str,\n    StringConstraints(\n        strip_whitespace=True,\n        min_length=1,\n    ),\n]\n\n\ndef _validate_non_empty_string(value: str) -> str:\n    if not value.strip():\n        msg = \"String must not be empty.\"\n        raise ValueError(msg)\n    return value\n\n\nNonEmptyString = Annotated[str, AfterValidator(_validate_non_empty_string)]\n\n\nclass WatsonxApiProviderAccountCreate(BaseModel):\n    \"\"\"WXO provider-account provider_data contract at API boundary.\n\n    This schema is owned by the WXO mapper and parsed once to validate the\n    provider-account provider_data payload before URL policy checks, credential\n    verification payload shaping, and DB field extraction.\n    \"\"\"\n\n    model_config = {\"extra\": \"forbid\"}\n\n    url: ValidatedUrl\n    tenant_id: Annotated[str | None, StringConstraints(strip_whitespace=True, min_length=1)] = None","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/langflow-ai/langflow/blob/976ec789d2886a86de109c044d089d68e96c9a35/src/backend/base/langflow/api/v1/mappers/deployments/watsonx_orchestrate/payloads.py#L23-L59","documentation":"Pydantic AfterValidator on NonEmptyString (used for fields like tool ids in the wxO API payload schemas): a string that survives stripping but is empty, or becomes empty after strip, fails with 'String must not be empty.' The enclosing request model is part of provider_data validation on deployment create/update, so FastAPI surfaces this as a 422 with this message inside the validation errors.","triggerScenarios":"POST/PATCH a wxO deployment with provider_data containing a whitespace-only or empty string where a NonEmptyString field is expected — e.g. upsert_tools[].tool_id = \"\" or \"   \", or a remove_tools entry that is blank.","commonSituations":"Programmatic request builders defaulting ids to empty strings instead of omitting the field; template/Jinja-generated payloads inserting blank variables; UI form submitting an untouched input.","solutions":["Send a real non-blank value for the field, or omit the field/item entirely if it is optional.","Trim client-side before sending: skip list entries whose value strips to empty.","If generating payloads from templates, guard interpolated ids with a falsy check so empty variables drop the key."],"exampleFix":"// before\n{\"upsert_tools\": [{\"tool_id\": \"   \", \"add_app_ids\": []}]}\n// after\n{\"upsert_tools\": [{\"tool_id\": \"my-tool-id\", \"add_app_ids\": []}]}","handlingStrategy":"validation","validationCode":"def clean_non_empty(v: str | None) -> str | None:\n    if v is None:\n        return None\n    v = v.strip()\n    return v or None  # drop blank instead of sending it\n\npayload = {k: clean_non_empty(v) for k, v in raw.items() if clean_non_empty(v) is not None}","typeGuard":"const isNonEmptyString = (v: unknown): v is string =>\n  typeof v === \"string\" && v.trim().length > 0;","tryCatchPattern":"try {\n  await api.post(\"/deployments\", body);\n} catch (e) {\n  if (e.response?.status === 422 && JSON.stringify(e.response.data).includes(\"String must not be empty\")) {\n    showFieldError(\"Blank values are not allowed; fill or remove the field.\");\n  }\n}","preventionTips":["Strip and drop blank strings client-side before serialization.","Skip optional list entries whose identifier is blank instead of submitting them.","Prefer omitting optional keys over sending empty strings."],"tags":["watsonx-orchestrate","pydantic","validation","http-422","empty-string"],"backgroundTag":null,"analyzedSha":"976ec789d2886a86de109c044d089d68e96c9a35","analyzedAt":"2026-08-14T18:23:12.227Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}