{"record":{"id":"8dee2162d28d8bc1","repo":"windmill-labs/windmill","slug":"invalid-flow-inputs-schema-invalidproperties-jo","errorCode":null,"errorMessage":"Invalid flow inputs schema: ${invalidProperties.join(', ')}","messagePattern":"Invalid flow inputs schema: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src/lib/components/copilot/chat/shared.ts","lineNumber":1453,"sourceCode":"\t\t\t}\n\t\t}\n\t}\n}\n\nexport async function buildSchemaForTool(\n\ttoolDef: ChatCompletionFunctionTool,\n\tschemaBuilder: () => Promise<FunctionParameters>\n): Promise<boolean> {\n\ttry {\n\t\tconst schema = await schemaBuilder()\n\n\t\t// if schema properties contains values different from '^[a-zA-Z0-9_.-]{1,64}$'\n\t\tconst invalidProperties = Object.keys(schema.properties ?? {}).filter(\n\t\t\t(key) => !/^[a-zA-Z0-9_.-]{1,64}$/.test(key)\n\t\t)\n\t\tif (invalidProperties.length > 0) {\n\t\t\tconsole.warn(`Invalid flow inputs schema: ${invalidProperties.join(', ')}`)\n\t\t\tthrow new Error(`Invalid flow inputs schema: ${invalidProperties.join(', ')}`)\n\t\t}\n\n\t\t// Anthropic requires input_schema.type to be present; flows with no inputs\n\t\t// can produce a sparse schema (e.g. { order: [] }) lacking it.\n\t\ttoolDef.function.parameters = { type: 'object', ...schema, additionalProperties: false }\n\n\t\t// recursively normalize provider-incompatible schema fragments\n\t\tnormalizeToolParameterSchema(toolDef.function.parameters)\n\n\t\t// OPEN AI models don't support strict mode well with schema with complex properties, so we disable it\n\t\tconst model = getCurrentModel()\n\t\tif (\n\t\t\tmodel.provider === 'openai' ||\n\t\t\tmodel.provider === 'azure_openai' ||\n\t\t\tmodel.provider === 'azure_foundry'\n\t\t) {\n\t\t\ttoolDef.function.strict = false\n\t\t}","sourceCodeStart":1435,"sourceCodeEnd":1471,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/frontend/src/lib/components/copilot/chat/shared.ts#L1435-L1471","documentation":"Before exposing a flow's inputs as a tool schema to the LLM, the copilot validates every property key against the pattern ^[a-zA-Z0-9_.-]{1,64}$ (also used by Windmill for path/name validation). Keys outside this charset or longer than 64 chars are collected and thrown as 'Invalid flow inputs schema: <keys>'. This exists because downstream providers (notably Anthropic) reject tool parameter names that violate their identifier rules.","triggerScenarios":"A flow whose inputs (args.json / OpenAPI-style schema) contains a property key with illegal characters — spaces, unicode, special symbols, empty string — or a key longer than 64 characters, when the chat builds the flow-inputs tool definition (shared.ts:1453).","commonSituations":"Flow inputs were hand-edited and a key like 'my input' or 'user@email' was used; a flow imported from elsewhere has keys with slashes or dots beyond the allowed pattern; a very long descriptive key exceeding 64 chars; non-ASCII localized key names.","solutions":["Rename the offending input keys in the flow's args schema to match ^[a-zA-Z0-9_.-]{1,64}$ (letters, digits, underscore, dot, hyphen).","Shorten any key longer than 64 characters.","Regenerate the flow inputs from the flow editor so keys are normalized automatically.","If the key cannot change, wrap the value under a compliant parent key and reference it accordingly."],"exampleFix":"// before (args.json)\n{\"properties\": {\"user name\": {\"type\": \"string\"}}}\n// after\n{\"properties\": {\"user_name\": {\"type\": \"string\"}}}","handlingStrategy":"validation","validationCode":"const KEY_RE = /^[a-zA-Z0-9_.-]{1,64}$/\nconst invalid = Object.keys(flowSchema.properties ?? {}).filter((k) => !KEY_RE.test(k))\nif (invalid.length) throw new Error(`Fix flow input keys before chat: ${invalid.join(', ')}`)","typeGuard":"function hasValidInputKeys(schema: { properties?: Record<string, unknown> }): boolean {\n  return Object.keys(schema.properties ?? {}).every((k) => /^[a-zA-Z0-9_.-]{1,64}$/.test(k))\n}","tryCatchPattern":"try {\n  const def = buildFlowInputsTool(schema)\n} catch (e) {\n  if (e.message.startsWith('Invalid flow inputs schema:')) {\n    const fixed = sanitizeKeys(schema) // slugify keys to [a-zA-Z0-9_.-]\n    def = buildFlowInputsTool(fixed)\n  }\n}","preventionTips":["Validate flow args.json keys at deploy/edit time against ^[a-zA-Z0-9_.-]{1,64}$.","Keep input keys under 64 characters.","Avoid spaces, unicode, and symbols in input names; use snake_case.","Regenerate inputs from the flow editor rather than hand-editing JSON."],"tags":["schema-validation","flow-inputs","copilot"],"backgroundTag":"schema-validation-failed","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}